Go语言 struct与& struct的区别

kwvwclae  于 2023-04-27  发布在  Go
关注(0)|答案(2)|浏览(182)
type test_struct struct {
    Message string
}

func (t *test_struct) SayP() {
    fmt.Println(t.Message)
}

func (t *test_struct) UpdateP(m string) {
    t.Message = m
}

func main() {
    ts := &test_struct{}
    ts.Message = "test"
    ts.SayP()
    ts.UpdateP("test2")
    ts.SayP()

    tsp := test_struct{}
    tsp.Message = "test"
    tsp.SayP()
    tsp.UpdateP("test2")
    tsp.SayP()
}

&test_struct{}test_struct{}有什么区别?

tsp := test_struct{}

不应该工作得很好

hgncfbus

hgncfbus1#

这些方法是为*test_struct定义的。这意味着,如果test_struct的示例是可寻址的,您仍然可以调用它的方法。在您的示例中,tstsp都是可寻址的,因此当您调用tsp.SayP时,tsp的地址将作为接收方传递。
在以下情况下,test_struct示例将不可寻址:

v:=map[string]test_struct{
  "a": test_struct{},
}
v["a"].SayP() // This will not work

上面,v[“a”]是不可寻址的,因为它是存储在map中的值的副本。因此,您不能调用SayP()。如果您声明:

v:=map[string]*test_struct{
  "a": &test_struct{},
}
v["a"].SayP() // This will  work

那么它将工作,因为v["a"]是可寻址的。

n9vozmp4

n9vozmp42#

go添加了语法糖(下面会有更多内容),允许你从一个具有结构类型的变量中毫无瑕疵地调用指针方法,所以你显示的代码行为“相同”。
如果你将值传递给一个函数,或者复制它,你会看到一个区别:

ts := &test_struct{}
    ts.Message = "test"

    ts2 := ts   // this is a pointer copy
    ts2.UpdateP("test2")
    ts.SayP()   // ts has also been modified (more exactly:
                // ts points to a struct which has been modified)

    tsp := test_struct{}
    tsp.Message = "test"

    tsp2 := tsp // this is a complete struct copy
    tsp2.UpdateP("test2")
    tsp.SayP()  // tsp hasn't been modified (tsp2 is a different struct in memory)

Playground:https://go.dev/play/p/-Yr2NCVix2g
语法糖的意思是:

  • 如果*T类型上有一个名为Foo的方法
  • 类型T上没有名为Foo的方法
  • vT类型的变量
  • [update]和v是 * 可寻址的 *(正如BurakSerdar在his answer中指出的那样)

调用v.Foo()是有效的,编译器会自动将其转换为(&v).Foo()

相关问题