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

Can't understand following behavior. Difference of d1 := &data{1}; d1 and d2 := data{1}; &d1. Both are pointer, right? But they behave differently. Whats happening here

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}
}

What is actually happening here?

This is all about use and assignment of values vs pointers.

In both cases, m[something] holds an address to a data. However, the important distinction is what d1 and d2 are.

d1 is of type *data:

The value of d1 is a pointer. When we assign &data{...} to d1, this changes the value of d1 to be a pointer to the new struct.

Since you are assigning, or changing the value of d1, the map still holds the old value.

d1 := &data{1}
fmt.Printf("d1    value: %p
", d1)
// d1    value: 0x10410020

d1 = &data{2}
fmt.Printf("d1    value: %p
", d1)
// d1    value: 0x10410024

As you can see: the address in memory that d1 is pointing to has changed. You are storing the value 0x10410020 in the map, so even if you change p1 to point to another address, the pointer inside the map still points to the original location.

The pointers look like:

m["d1"] -----> data{1}

d1      -----> data{2}

d2 is of type data:

In the case of d2, you are storing the address of the variable d2. On assignment, we change the value of d2, but its address does not change.

d2 := data{1}
fmt.Printf("d2    address: %p
", &d2)
// d2    address: 0x10410028

d2 = data{2}
fmt.Printf("d2    address: %p
", &d2)
// d2    address: 0x10410028

Since this address 0x10410028 is what you are storing in the map, it is pointing to the value of d2 which changes on assignment.

The pointers in this look like (they're both pointers to the same area of memory. Sorry, it's hard to draw arrows in ascii):

m["d2"] -----\
             data{2}
d2      -----/