数组的值传递
func main() {arrayA := [2]int{100, 200}var arrayB [2]intarrayB = arrayAfmt.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]
