在Go中,为结构类型使用setter不能按预期工作 [英] In Go, using a setter for a struct type does not work as anticipated

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

问题描述

使用结构体的setter函数,但不能按预期工作:

 
包主体

导入fmt

type T struct {Val string}

//此setter似乎不起作用
func(t T)SetVal(s string){
t.Val = s
}

//这个setter,使用ptr到T,似乎工作正常
func(t * T)SetVal2(s string) {
(* t).Val = s
}

func main(){
v:= T {abc}
fmt.Println (v)//打印{abc}
v.SetVal(pdq)
fmt.Println(v)//打印{abc},期待{pdq}!
v.SetVal2(xyz)
fmt.Println(v)//打印{xyz}!
}

我缺少一些基本的理解 - 为什么没有 SetVal work?



这种行为类似于设置 reflect 中的值,这只有在提供指向对象与对象本身不同

解决方案

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

您可以通过打印出有问题的结构的实际地址来证明它的工作方式:

 









$ b $ )SetVal(s string){
fmt.Printf(复制地址是%p \ n,& t);


func(t * T)SetVal2(s string){
fmt.Printf(指针参数为%p \ n,t);

$ b func main(){
v:= T {abc}
fmt.Printf(v的地址是%p \ n, &安培; 5);
v.SetVal(pdq)
v.SetVal2(xyz)
}

上面的代码在Go操作系统中运行时产生了这个输出结果:

  Address of 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\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")
}

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 is seems to be exactly the same way that C structs / function parameters work, by the way.

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

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