Go语言没有引用类型,可以查看Go语言创始人Robert Griesemer的提交(2013-04-03):
https://github.com/golang/go/commit/b34f0551387fcf043d65cd7d96a0214956578f94
所有的函数入参都是值传递(即值拷贝),没有什么所谓的引用传递。map、chan、切片(slice)等类型的变量入参,从结果来看似乎是引用传递,但本质原因是这些类型的数据结构设置了一个字段来保存指针,在函数体内更改数据都是通过指针来进行的。
查看切片(slice)源码文件“{Go安装目录}/src/runtime/slice.go”就可以看到切片的数据结构有一个字段保存指向数组的指针。
所以Go语言没有值类型和引用类型的区分,如果非要区分应该是数据结构是否有指针字段。
无指针:基本数据类型(int、float、bool、string)、数组、结构体(struct)
有指针:map、chan、切片(slice)、接口(interface)、函数(func)、指针
无指针的数据类型变量通常分配在栈内存,栈内存在函数调用完后会被释放;有指针的数据类型变量通常分配在堆内存,并通过GC(Garbage Collection)回收。
通过下面的代码可以直观地看到,切片变量入参实际上传入的是指针。
package main
import "fmt"
func Test(n []string) {
n[0] = "天皇·" + n[0]
n[1] = "地皇·" + n[1]
n[2] = "人皇·" + n[2]
}
func main() {
name := []string{"燧人", "神农", "伏羲"}
Test(name)
fmt.Println(name) // [天皇·燧人 地皇·神农 人皇·伏羲]
}