对结构类型使用 setter 无法按预期工作 [英] Using a setter for a struct type does not work as anticipated

查看:22
本文介绍了对结构类型使用 setter 无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对结构使用 setter 函数,但未按预期工作:

package main导入fmt"类型 T 结构 { Val 字符串 }//这个 setter 似乎不起作用func (t T) SetVal( s 字符串) {t.Val = s}//这个 setter,使用 ptr 到 T,似乎工作正常func (t *T) SetVal2( s 字符串) {(*t).Val = s}功能主(){v := T{"abc"}fmt.Println( v )//打印 {abc}v.SetVal("pdq")fmt.Println( v )//打印 {abc},期待 {pdq}!v.SetVal2("xyz")fmt.Println( v )//打印 {xyz}!}

我缺少一些基本的理解 - 为什么 SetVal 不起作用?

行为类似于在 reflect 中设置值,它仅在提供指向对象的指针与对象本身相比时才有效

解决方案

这里是你缺少的基本理解:当一个结构体作为指针传递给函数时,该函数可以修改原始结构体,因为它有一个指向它.然而,当一个结构体通过它的值传递给一个函数时,那么这个结构体的新副本实际上只是为那个函数调用而创建的,对这个结构体的这个新副本的任何修改都不会影响原始结构体.

您可以通过打印出相关结构的实际地址来证明这是它的工作方式:

包主导入fmt"类型 T 结构 { Val 字符串 }func (t T) SetVal( s 字符串) {fmt.Printf("复制地址为%p
", &t);}func (t *T) SetVal2( s 字符串) {fmt.Printf("指针参数为 %p
", t);}功能主(){v := T{"abc"}fmt.Printf("v 的地址是 %p
", &v);v.SetVal("pdq")v.SetVal2("xyz")}

当我在 Go Playground 中运行上面的代码时会产生这个输出:

v 的地址为 0xf840001290副本地址为 0xf8400013e0指针参数是 0xf840001290

注意打印出的第一个和第三个指针是如何相等的,这意味着它们是相同的结构.但是第二个指针不同,因为它是一个副本.

顺便说一下,这似乎与 C 结构/函数参数的工作方式完全相同.

Using a setter function for a struct, but not working as anticipated:

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}!
}

I am missing some fundamental understanding - why doesn't SetVal work?

the behavior is similar to setting values in reflect which only works if provided a pointer to the object as versus the object itself

解决方案

Here is the fundamental understanding you are missing: when a struct is passed in to a function as a pointer, the function can modify the original struct because it has a pointer to it. However, when a struct is passed in to a function via its value, then a NEW copy of the struct is actually created just for that function call, and any modifications to this new copy of the struct will not affect the original struct.

You can prove that this is the way it works by printing out the actual addresses of the structs in question:

package main

import "fmt"

type T struct { Val string }

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

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

func main() {
        v := T{"abc"}
        fmt.Printf("Address of v is %p
", &v);
        v.SetVal("pdq")
        v.SetVal2("xyz")
}

The code above results in this output when I run it in the Go playground:

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290

Notice how the first and third pointer printed out are equal, which means they are the same struct. But the second pointer is different because it is a copy.

This seems to be exactly the same way that C structs / function parameters work, by the way.

这篇关于对结构类型使用 setter 无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆