【问题标题】:pointer receiver vs value receiver指针接收器与值接收器
【发布时间】:2017-01-20 17:11:59
【问题描述】:

情况:

我了解了指针接收器值接收器。据我了解:如果要修改对象本身,则需要使用指针接收器。我在go documentation 中阅读了有关接口的更多信息,并发现了这段代码:

type Sequence []int

// Methods required by sort.Interface.
func (s Sequence) Len() int {
    return len(s)
}
func (s Sequence) Less(i, j int) bool {
    return s[i] < s[j]
}
func (s Sequence) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}
  • LessLen 方法正在使用 值接收器,这是有道理的,因为它们正在返回数据而不是修改 Sequence 状态。

  • 但在Swap 示例中,我很好奇为什么它看起来正在尝试修改其状态时仍在使用值接收器

问题:

这是一个错误,还是我对值/指针接收器的理解在某些方面存在缺陷?

【问题讨论】:

  • Sequence 是一个引用类型,因此Swap 函数将交换切片的基础值。一篇关于切片的好文章可以看这里:blog.golang.org/go-slices-usage-and-internals
  • 你没有修改s。您正在修改 s[i]s[j]

标签: pointers go go-interface


【解决方案1】:

为了扩展@squiguy 的评论,切片对象的值本身就是对底层数组的引用,包括指向数组中切片开始处的元素的指针、切片的长度以及切片的容量(底层数组中从切片开头到数组结尾的元素数)。当你将切片传递给函数时,是按值传递的就是上面的信息,所以函数内的切片仍然引用同一个底层数组。这就是 Swap 能够交换切片中的元素的方式,即使切片本身是按值传递的。

【讨论】:

  • 这很有意义,我不明白切片总是对数组的引用。那么如果这是一种特殊情况,Go 中是否还有其他类似的类型?
  • 地图的行为方式类似。如果您将映射传递给函数并且函数对映射进行更改,则调用者将看到该更改。通道也属于这一组(引用类型),但可能更明显的是,如果将通道传递给函数,则函数和调用者都引用同一个通道。
猜你喜欢
  • 2015-03-02
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 2018-01-20
  • 2018-10-14
相关资源
最近更新 更多