指针的这种用法有什么区别(a:=&A; a)和(b:= B;&b)

问题描述 投票:1回答:1

无法理解以下行为。 d1 := &data{1}; d1d2 := 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}
}

这里到底发生了什么?

pointers go
1个回答
5
投票

这都是关于值和指针的使用和assignment

在这两种情况下,m[something]都持有data的地址。然而,重要的区别是d1d2

d1 is of type *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}

d2 is of type 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      -----/
© www.soinside.com 2019 - 2024. All rights reserved.