无法理解以下行为。 d1 := &data{1}; d1
和d2 := data{1}; &d1
的差异。两者都是指针,对吗?但他们的行为却不同。发生什么事了
package main
import "fmt"
type data struct {
value int
}
func main() {
m := make(map[string]*data)
d1 := &data{1}
m["d1"] = d1 // Here putting &{1}
d1 = &data{2}
fmt.Println(m["d1"])
// &{1}
d2 := data{1}
m["d2"] = &d2 // Here putting &{1}
d2 = data{2}
fmt.Println(m["d2"])
// &{2}
}
这里到底发生了什么?
答案 0 :(得分:5)
这完全是关于值和指针的使用和assignment。
在这两种情况下,m[something]
都会保存data
的地址。
但是,重要的区别在于d1
和d2
。
*data
: d1
的值是一个指针。当我们将&data{...}
分配给d1
时,会将d1
的值更改为指向新结构的指针。
由于您要分配或更改d1
的值,因此地图仍保留旧值。
d1 := &data{1}
fmt.Printf("d1 value: %p\n", d1)
// d1 value: 0x10410020
d1 = &data{2}
fmt.Printf("d1 value: %p\n", d1)
// d1 value: 0x10410024
如您所见:d1
指向的内存中的地址已更改。您将值0x10410020
存储在地图中,因此即使您将p1
更改为指向另一个地址,地图内的指针仍指向原始位置。
指针看起来像:
m["d1"] -----> data{1}
d1 -----> data{2}
data
:如果是d2
,则表示您正在存储变量d2
的地址。在分配时,我们更改d2
的值,但其地址不会更改。
d2 := data{1}
fmt.Printf("d2 address: %p\n", &d2)
// d2 address: 0x10410028
d2 = data{2}
fmt.Printf("d2 address: %p\n", &d2)
// d2 address: 0x10410028
由于此地址0x10410028
是您在地图中存储的地址,因此它指向d2
的值,该值会在分配时更改。
这个中的指针看起来像是(它们指向同一个记忆区域的指针。抱歉,在ascii中绘制箭头很难):
m["d2"] -----\
data{2}
d2 -----/