【问题标题】:Any documentation/article about the `&MyType{}` pattern in golang?任何关于 golang 中的 `&MyType{}` 模式的文档/文章?
【发布时间】:2017-03-03 16:01:53
【问题描述】:

在我查看的大多数 golang 代码库中,人们通过引用使用类型:

type Foo struct {}
myFoo := &Foo{}

我通常采取相反的方法,将所有内容作为副本传递,并且仅在我想对值执行破坏性操作时通过引用传递,这使我可以轻松发现破坏性函数(这相当罕见)。

但是看到引用是司空见惯的,我想这不仅仅是品味问题。我知道复制值是有代价的,这是否会改变游戏规则?或者还有其他为什么首选参考的原因?

如果有人能指出一篇文章或文档说明为什么首选参考文献,那就太好了。

谢谢!

【问题讨论】:

  • 嗨@icza,感谢您指出这些,在我输入时它们并没有作为建议出现。第一个似乎确实解决了同样的问题,但所选答案 1/ 指的是“指南”和“良好做法”,但没有明确说明原因(但仍有很多有用的信息!)和 2/ 似乎建议实际上避免默认使用 &Type{} :) 我想在这里清楚地说明支持这种模式的原因可能很有用。
  • 这不仅仅关乎速度,Olivier。假设您构建了一堆Foos,并将这些值放入几个不同的容器(例如切片)中,按值复制它们。这意味着每个容器现在都有每个源值的副本,并且在这些容器中的任何一个中更改它们都不会对其他容器产生任何影响。有时可以,有时则不行。在每种情况下,您都应该考虑要将什么语义放入您正在创建的类型的值中,以及您打算如何使用该类型的值。
  • 确实 :) 在那个例子中,在变量初始化时取消引用是否提供了比使用 append( myslice, &myItem ) 更多的功能?

标签: go


【解决方案1】:

Go 是按值传递。我尝试尽可能使用您的示例中的引用来消除考虑不复制对象的心理过程。 Go 主要用于网络和扩展,这将性能放在首位。正如你所说的那样明显的缺点是,接收方法可以破坏指针指向的对象。

否则没有关于你应该使用哪个规则。两者都很好。

另外,与问题有些相关,来自 Go 文档:Pointers vs. Values

【讨论】:

  • 您好 Teoman,感谢您的回答!我将做一个基准来尝试衡量复制的实际成本。也感谢您的文档,但我实际上想知道有关 &Type{} 模式的文档:) 我会澄清这个问题。
  • 好的,这是一个基准测试:gist.github.com/oelmekki/d7e93170b00278d73ccea052a2ee7ed7 1B 函数调用的差异约为 500 毫秒。所以我想结论是,对于极其密集的计算(比如你提到的网络)使用引用是值得的,但对于较小的应用程序来说就不那么重要了。
  • 为了确定,我再次运行基准测试,在Name 字段中设置了一个实际值,这不会改变结果。
  • @OlivierElMekki:取消引用指针可能会很昂贵,而且 CPU 可以同时复制大量数据。小于缓存行或 2(大多数是)的结构不会从指针中获得性能优势。程序的逻辑,共享地址以实现可变性或复制值,将决定使用哪个。
  • @OlivierElMekki:基准测试很难做到正确,尤其是需要考虑数据局部性、CPU 特定缓存行为和分支预测的微基准测试。在您的示例中,编译器可以选择完全删除这些调用中的任何一个,并且您可以完全计时其他事情,因为您没有做任何实际工作。使用当前的编译器和基准测试工具,这两个调用将花费完全相同的时间,可能是因为它们被优化了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 2017-11-05
  • 2020-02-14
  • 1970-01-01
  • 2013-06-25
相关资源
最近更新 更多