go - 为什么忘记了struct字段值

标签 go

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

这是一个简单的例子:

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不粘?

这个例子有效: 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()
}

最佳答案

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

为了说服自己,您可以打印mainSetMember 方法中对象的地址。

当使用指针接收器时:

主要内容:

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

SetMember 中(应该与 main 中的相同):

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

当使用值接收者时:

主要是:

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

SetMember 中(应该与 main 中的不同):

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

关于go - 为什么忘记了struct字段值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33337914/

相关文章:

go - 无法获取额外信息。来自 gin-jwt 中的登录响应

go - 处理 panic 和延迟函数

sql - 为什么在 go sql 包中使用准备好的语句而不是 Query/Exec?

go - 如何在终端中使用 `Erase the scroll-back (aka "保存的行")`

go - 如何使用 golang 在非根路径上提供 index.html

google-app-engine - 带有 Golang : How do you parse URL path segments as variables? 的 Google App Engine

memory-management - CGO:如何使用 malloc 从 go 中释放在 C 中分配的内存以避免内存泄漏

go - 如何在 Visual Studio Code 中使用 Delve 调试器进行远程调试

go - 检查不同 Go Map 类型中的重复键

unit-testing - 使用gocheck测试go(golang)代码,suite功能如何使用?