英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论