首页 > 后端开发 > Golang > 为什么我的 Go Struct Setter 函数没有修改原始结构?

为什么我的 Go Struct Setter 函数没有修改原始结构?

Mary-Kate Olsen
发布: 2024-12-21 10:00:17
原创
699 人浏览过

Why Doesn't My Go Struct Setter Function Modify the Original Struct?

了解结构体类型的 Setter

在 Go 中,可以通过 setter 函数修改结构体。但是,在对结构类型使用 setter 时,某些行为可能是无法预料的。考虑以下示例:

package main

import "fmt"

type T struct { Val string }

// this setter seems not to work
func (t T) SetVal(s string) {
    t.Val = s
}

// this setter, using ptr to T, seems to work ok
func (t *T) SetVal2(s string) {
    (*t).Val = s
}

func main() {
    v := T{"abc"}
    fmt.Println(v)        // prints {abc}
    v.SetVal("pdq")
    fmt.Println(v)        // prints {abc}, was expecting {pdq}!
    v.SetVal2("xyz")
    fmt.Println(v)        // prints {xyz}!
}
登录后复制

问题出现了:为什么 SetVal 函数没有按预期修改原始结构?

理解值语义

主要区别在于结构体​​如何传递给函数。当按值传递结构体时(如 SetVal),会在函数内创建该结构体的副本。函数内所做的任何更改都只会影响此临时副本,而原始结构保持不变。

但是,当通过指针传递结构时(如 SetVal2 中),函数可以访问内存中的原始结构。函数内所做的任何更改都将直接反映在原始结构中。

价值语义证明

这可以通过打印所涉及结构的内存地址来说明:

package main

import "fmt"

type T struct { Val string }

func (t T) SetVal(s string) {
    fmt.Printf("Address of copy is %p\n", &t)
}

func (t *T) SetVal2(s string) {
    fmt.Printf("Pointer argument is %p\n", t)
}

func main() {
    v := T{"abc"}
    fmt.Printf("Address of v is %p\n", &v)
    v.SetVal("pdq")
    v.SetVal2("xyz")
}
登录后复制

此代码将产生输出类似于:

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290
登录后复制

注意,打印的第一个和第三个地址是相同的,表明它们引用相同的结构体。然而,第二个地址不同,代表在 SetVal 中创建的临时副本。

以上是为什么我的 Go Struct Setter 函数没有修改原始结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板