在 Go 语言中,「函数的参数传递只有值传递」,而且传递的实参都是原始数据的一份拷贝。如果拷贝的内容是值类型的,那么在函数中就无法修改原始数据;如果拷贝的内容是指针(或者可以理解为引用类型 map、chan 等),那么就可以在函数中修改原始数据。
例子:
// 函数参数为切片类型
func foo(s []int) {
// 这里拿到的切片类型s,是一个新的切片
s[0] = 666
}
func main() {
// 定义数值
slice := []int{1,2}
fmt.Println(slice) // [1 2]
foo(slice)
fmt.Println(slice) // [666 2]
}
Go 中切片的底层结构是这样的
type slice struct {
array unsafe.Pointer
len int
cap int
}
而当你将切片作为实参传给函数时,函数是会拷贝一份实参的结构和数据,生成另一个切片,实参切片和形参切片,不仅是长度、容量相等,连指向底层数组的指针都是一样的。