传参和传引用问题,在golang 的一些教材中多有描述,现在再温习一遍

  1. Golang的函数调用参数全部是传值得,包括 slice/map/chan 在内的所有类型,没有传引用的说法

       所有类型的函数参数都是传值的,包括slice/map/chan等基础类型和自定义的类型

       但是因为 slice 和 map/chan 底层结构的差异,又导致了它们传值得影响并不完全等同

归纳如下:

  • Golang 所有函数参数都是传值的

  • map/slice/chan 都是传值,不是传引用

  • map/chan 对应指针,和引用类似

  • slice是结构体和指针的混合体

slice 含有 values/count/capacity 等信息,是按值传递

slice中的values是指针,按值传递

按值传递的slice 只能修改values指向的数据,其他都不能修改

  1. Golang语言有引用的说法吗?

Golang的语言也是有传引用的地方的,但是不是函数的参数,而是闭包对外部环境是通过引用访问的

coding:

func main() {

    a:= new(int)  

    fmt.Println(a) 

    func(){ a= nil }() 

    fmt.Println(a)

}

输出为:

0xc010000000 <nil>

因为闭包是通过引用的方式使用的外部环境的a变量,因此可以直接修改a的值。

如果不想修改a的值,避免闭包的副作用,回避的办法是通过 参数传值或 每次闭包构造不同的临时变量

方法一:

for i:=0; i<5; i++ {

    i := i

    defer func() {

        fmt.Printf(" %d ", i )

    }()

}


方法二:

for i:= 0; i<5; i++ {

    defer  func(i int) {

        fmt.Printf("%d ", i)

        }(i)

}

  • 总结:

  • 函数参数传值,闭包传引用

  • map、chan 本身是指针,近似于引用传递

  • slice 含有 values/count/capacity 等信息,是按值传递

  • 按值传递的 slice 只能修改values指向的数据

  • slice是结构体和指针的混合体