数组的值传递
func main() {
arrayA := [2]int{100, 200}
var arrayB [2]int
arrayB = arrayA
fmt.Printf("arrayA : %p , %v\n", &arrayA, arrayA)
fmt.Printf("arrayB : %p , %v\n", &arrayB, arrayB)
testArray(arrayA)
}
func testArray(x [2]int) {
fmt.Printf("func Array : %p , %v\n", &x, x)
}
// arrayA : 0xc4200bebf0 , [100 200]
// arrayB : 0xc4200bec00 , [100 200]
// func Array : 0xc4200bec30 , [100 200]
go的数组是值类型,赋值和函数参数传递都会复制整个数组。可以看到,三个内存地址都不同,这也就验证了 Go 中数组赋值和函数传参都是值复制的。那这会导致什么问题呢? 每次传参都用数组,假设数组的元素大小有100w, 在64位的机器上就需要花费800w字节,8MB的内存,开销大得惊人。所以我们一般使用指针传递:
func main() {
arrayA := [2]int{100, 200}
testArrayPoint1(&arrayA) // 1.传数组指针
arrayB := arrayA[:]
testArrayPoint2(&arrayB) // 2.传切片
fmt.Printf("arrayA : %p , %v\n", &arrayA, arrayA)
}
func testArrayPoint1(x *[2]int) {
fmt.Printf("func Array : %p , %v\n", x, *x)
(*x)[1] += 100
}
func testArrayPoint2(x *[]int) {
fmt.Printf("func Array : %p , %v\n", x, *x)
(*x)[1] += 100
}
// func Array : 0xc4200b0140 , [100 200]
// func Array : 0xc4200b0180 , [100 300]
// arrayA : 0xc4200b0140 , [100 400]
记住,在golang中,区别一个变量是数组还是切片,就看有没有定义长度
array := []int{10, 20, 30, 40}
fmt.Printf("%p\n %v\n", &array, array)
copy(array, array[1:])
fmt.Printf("%p\n %v\n", &array, array)
0xc000258e00
[10 20 30 40]
0xc000258e00
[20 30 40 40]