为什么结构体字段的值会被遗忘?

huangapple go评论102阅读模式
英文:

Why is the struct field value forgotten

问题

这是一个简单的示例:

package main

import "fmt"

type Holder struct {
    i int
}

func (h Holder) SetMember(i1 int) {
    fmt.Println(i1)
    h.i = i1
}

func (h Holder) GetMember() int {
    fmt.Println(h.i)
    return h.i
}

func main() {
    c := Holder{i:3}
    c.SetMember(5)
    c.GetMember()
}

我可能对golang有一个非常基本的误解。为什么在设置后值5没有保留下来?

这个示例可以正常工作:

package main

import "fmt"

type Holder struct {
    i int
}

func (h *Holder) SetMember(i1 int) {
    fmt.Println(i1)
    h.i = i1
}

func (h *Holder) GetMember() int {
    fmt.Println(h.i)
    return h.i
}

func main() {
    c := &Holder{i:3}
    c.SetMember(5)
    c.GetMember()
}
英文:

http://play.golang.org/p/wU44VOa_uP

Here's a simple example:

package main

import "fmt"

type Holder struct {
	i int
}

func (h Holder) SetMember(i1 int) {
	fmt.Println(i1)
	h.i = i1
}

func (h Holder) GetMember() int {
	fmt.Println(h.i)
	return h.i
}

func main() {
	c := Holder{i:3}
	c.SetMember(5)
	c.GetMember()
}

I'm probably missing a very basic truth about golang.
Why doesn't the value 5 stick after setting it?

This example works:
http://play.golang.org/p/j8hdKWPdsc

package main

import "fmt"

type Holder struct {
	i int
}

func (h *Holder) SetMember(i1 int) {
	fmt.Println(i1)
	h.i = i1
}

func (h *Holder) GetMember() int {
	fmt.Println(h.i)
	return h.i
}

func main() {
	c := &Holder{i:3}
	c.SetMember(5)
	c.GetMember()
}

答案1

得分: 2

在第二个示例中,你传递的是结构体对象本身,你是一个指针接收器。你看到了变化,因为你实际上修改了原始对象。在第一个示例中,你传递的是包含相同值的对象的副本,你使用的是值接收器。你看不到变化,因为你的原始对象没有被修改。

为了验证这一点,你可以在main函数和SetMember方法中打印对象的地址。

使用指针接收器时:

main函数中:

fmt.Printf("address in main: %p\n", c)

SetMember函数中(应该与main函数中的地址相同):

fmt.Printf("address in SetMember: %p\n", h)

使用值接收器时:

main函数中:

fmt.Printf("address in main: %p\n", &c)

SetMember函数中(应该与main函数中的地址不同):

fmt.Printf("address in SetMember: %p\n", &h)
英文:

In the second example you passing the struct object itself, you are a pointer receiver. You see the change because you have actually modified the original object. In the first example you are passing the copy of the object that contains the same values, you are using a value receiver. You don't see the change because your original object was not changed.

To convince yourself, you can print the addresses of the objects inside main and your SetMember method.

When using pointer receiver:

In main:

fmt.Printf("address in main: %p\n", c)

In SetMember (should be the same as in main):

fmt.Printf("address in SetMember: %p\n", h)

When using value receiver:

In main:

fmt.Printf("address in main: %p\n", &c)

In SetMember (should be different from what is in main) :

fmt.Printf("address in SetMember: %p\n", &h)

huangapple
  • 本文由 发表于 2015年10月26日 11:10:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/33337914.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定