考虑以下示例。我不完全了解“后台”会发生什么,并寻求解释。从主函数Foo调用时,此版本似乎复制了该结构AddToEntry。正确的?如何在代码中“证明”这一点?当go复制该结构时,我只是在操纵该结构的副本,当我返回该main函数时,是否像以前一样看到原始文件?当我希望有一个指针(请参见代码中的注释)时,一切都很好,没有复制我的结构。如何避免这种“错误”?如何确定不复制该结构?是否有可能对此进行编译时/运行时检查,或者我要小心吗?package mainimport ( "fmt")type Foo struct { Entry []string}func MakeFoo() Foo { a:=Foo{} a.Entry = append(a.Entry,"first") return a}// if I change (f Foo) to (f *Foo), I get // the "desired" resultfunc (f Foo) AddToEntry() { f.Entry = append(f.Entry,"second")}func main() { f:=MakeFoo() fmt.Println(f) // {[first]} f.AddToEntry() fmt.Println(f) // {[first]}}
2 回答
青春有我
TA贡献1784条经验 获得超8个赞
您的方法签名为func (f Foo) AddToEntry()
。方法的工作方式与以下方式f.AddToEntry()
相同:
g := Foo.AddToEntry g(f)
接收器只是另一个参数。为什么这很重要?当您传递结构并在函数中对其进行修改时会发生什么?在C,Go和其他按值传递语言中,参数中给出的结构仅是副本。因此,您不能修改原始文件。只返回新的结构。
定义时func (f *Foo) AddToEntry()
,您正在将接收器(第一个参数)定义为指针。显然,给定一个指针,您可以修改原始结构。隐藏的是您在Go中访问结构时隐式引用。换句话说,(*ptrFoo).Entry
与ptrFoo.Entry
Go中的相同。
因此,这里的问题是,对于那些不习惯的人,语法隐藏了一些正在发生的事情。在C语言中,除非传递了指向结构的指针,否则您将永远无法编辑该结构。Go中也会发生同样的情况。您需要使用指针接收器才能修改接收的内容。
- 2 回答
- 0 关注
- 239 浏览
添加回答
举报
0/150
提交
取消