我认为,您的主要问题是您对问题中出现的两个概念都不太了解。
让我们从指针开始。当您不使用指针时,赋值意味着创建先前值的简单副本。新值与前一个值没有任何约束。这意味着如果您更改旧值或新值,它不会影响第二个值。这对于原始类型(如 ints、bool、string)和结构是正常的。
a := 1
b := a
a++ // a was changed, but value of b does not change at all
现在是指针——它指向内存中的一些空间。为简单起见,我们创建了两个指针,它们都指向同一个地方。
package main
import (
"fmt"
)
func main() {
type student struct {
name string
age int
}
p1 := &student{"hongseok", 13} // this mean create a new student, but we want only address of student, not value
p2 := p1
(*p1).age = 15 // because p1 and p2 point to same memory (*p2).age also changed
fmt.Println("1.", p2.age) // 15
p2.age = 32 // in golang I could write (*p2).ago or p2.ago this is the same
fmt.Println("2.", p1.age) // 32
fmt.Println("3.",p1, "==", p2)
fmt.Printf("4. %p == %p\n", p1, p2)
// But now I force point p2 to new place
p2 = &student{"another student", 12}
fmt.Println("5.", p1, "!=", p2)
fmt.Printf("6. %p == %p\n", p1, p2)
p1.age = 14 // does it influce p2.age? no! Why? Because it is in different address
fmt.Println("7.", p1, "!=", p2)
// but could is somehow force that point to same address ? Of course
p2 = p1 // p2 will point to same place as p1 and old value of p2 will be freed by garbage collector
}
不要混淆——指针也可以指向命名值。
a := 42 // means allocate memory for integer, and we give that memory name "a"
p := &a
*p++ // it change value of a
a = 5 // and of course this change value of *p
现在回到方法,接收器是/不是指针。如果方法的接收者是指针,这意味着您可以更改它的值 - 就像我在几行前所做的那样。
如果方法接收器不是指针,这意味着 - 在调用方法之前,将创建一个结构副本,并在该副本上调用方法。你当然可以更改副本的价值,但它不会影响原始价值。