【发布时间】:2017-04-07 08:12:15
【问题描述】:
我想探讨一下当我们尝试复制变量时内存是如何分配的。我做了一些测试,这让我很困惑:
func testArrayAddress() {
var a [3]int
b := a
fmt.Printf("address of a %p and of b %p \n", &(a[0]), &(b[0]))
}
输出是:
address of a 0xc8200126e0 and of b 0xc820012700
但是我假设 a 和 b 指向同一个数组,所以第一个元素的起始地址应该相同?
这让我怀疑当我们执行语句b := a 时发生了什么?本来我以为初始化变量a的时候它只会为数组分配一个内存块,而b := a让b指向同一个内存位置,后来就无法解释为什么第一个元素的地址不是相同(应该是相同的元素)。
我改了第一行代码:
func testArrayAddress() {
var a = []int{1, 2, 3}
b := a
fmt.Printf("address of a's first element %p and of b %p \n", &(a[0]), &(b[0]))
}
那么输出是:
address of a's first element 0xc8200126e0 and of b 0xc8200126e0
现在它给了我同样的结果。
我想问的问题是:
在 Golang 中,当我们做变量复制(
b := a)时,我们是否也在内存中创建数据副本?不可变类型和可变类型是否相同?如果我们也复制可变类型(例如数组),它如何实现修改变量也会影响其他类型(
a[0] = 42会影响b[0])?[]int类型与我在上一个案例中测试的[number]int类型有何不同?
【问题讨论】:
-
这在 Tour of Go (tour.golang.org) 和关于数组 blog.golang.org/slices 和切片 blog.golang.org/go-slices-usage-and-internals 的博客文章中得到了很好的解释。简短回答:
b := a总是复制一份。 Go 中没有不可变的类型。 2)无法使用数组,这就是切片的用途。 3)[]int是一个切片,[3]int是一个数组。请仔细阅读tour.golang.org/moretypes/6 和以下幻灯片。