Golang中的函数 |青训营笔记

25 阅读2分钟

这是我参与「第五届青训营 -后端场」笔记创作活动的第2篇笔记

函数 一等公民

 func div(a, b int) (q, r int) {
 ​
     return a / b, a % b
 }
复制代码
  • 函数返回多个值时可以起名字
  • 仅用于非常简单的函数
  • 对于调用者而言没有区别

函数式编程语言

函数的参数,返回值,函数体内都可以有函数

 func apply(op func(int, int) int, a, b int) int {
     p := reflect.ValueOf(op).Pointer()
     opName := runtime.FuncForPC(p).Name() //拿到函数名
     fmt.Printf("Calling function %s with args "+"(%d, %d)\n", opName, a, b)
     return op(a, b)
 }
 ​
 func pow(a, b int) int {
     return int(math.Pow(float64(a), float64(b)))
 }
 func main() {
 ​
     fmt.Println(apply(pow, 3, 4))
     //Calling function main.pow with args (3, 4) 81
             
 }
复制代码

可变参数列表

 func sum(values ...int) int {
     sum := 0
     for i := range values {
         sum += values[i]
     }
     return sum
 }
 func main() {
     fmt.Println(sum(1,2,3,4,5)) //15
 }
复制代码

指针(重要)

  • 指针不能运算

如果用var x int 声明一个变量x,那么&x(取x变量的内存地址)表达式将产生一个指向该整数变量的指针

指针对应的数据类型是*int

若指针名字为p,那么可以说“p指针指向变量x”,或者“p指针保存了x变量的内存地址

 x := 1
 p := &x   //p, of type *int ,points to x
 fmt.Prinln(*p)  //"1"
 *p = 2   //equivalent to x = 2
 fmt.Println(x)  // "2"
复制代码

参数传递

C++中

  • 值传递 : 拷贝
  • 引用传递: 不拷贝

Go中

Go语言中只有值传递(拷贝)一种方式

方法一

 func swap(a, b *int) {
     *b, *a = *a, *b
 }
 ​
 func main() {
     a, b := 3,4
     swap(&a, &b)
     fmt.Println(a, b) //4 3
 }
复制代码

方法二

 func swap(a, b int) (int, int) {
     return b, a
 }
 ​
 func main() {
     a, b := 3,4
     swap(a, b)
     fmt.Println(a, b) //4 3
 }
复制代码

数组Array

  • 数量写在类型前
  • range 的三种用法
  • 数组的遍历
 package main
 ​
 import "fmt"
 ​
 func main() {
     var arr1 [5]int
     arr2 := [3]int{1, 3, 5}          //需要告诉初值
     arr3 := [...]int{2, 4, 6, 8, 10} //
 ​
     var grid [4][5]int
 ​
     fmt.Println(arr1, arr2, arr3)
     fmt.Println(grid)
 ​
     for i, v := range arr3 {
         fmt.Println(i, v)
     }
     //for _, v := range arr3 {
     //fmt.Println(v)
     //}
 ​
 }
复制代码

为什么要用range?

  • 意义明确美观,C++没有类似能力
  • Java Python :只能for each value,不能同时获取i,v
  • 除了数组,其他地方也会用到
  • 在Go语言中一般不直接使用数组,而是使用切片

数组是值类型

  • [10]int 和 [20]int 是不同类型
  • 调用func f(arr [10]int) 会 拷贝 数组
 func printArray(arr *[5]int) {
     arr[0] = 100
     for i, v := range arr {
         fmt.Println(i, v)
     }
 }
 ​
 func main() {
     var arr1 [5]int
     arr3 := [...]int{2,4,6,8,10}
     fmt.Println("printArray(&arr1)")
     printArray(&arr1)
     fmt.Println("printArray(&arr3)")
     printArray(&arr3)
     fmt.Println("arr1 and arr3")
     fmt.Println(arr1, arr3)
 }

作者:devinroot
链接:juejin.cn/post/710868…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。