Go's value method receiver vs pointer method receiver

huangapple go评论150阅读模式
英文:

Go's value method receiver vs pointer method receiver

问题

我已经阅读了《Go之旅》和《Effective Go》,http://golang.org/doc/effective_go.html#pointers_vs_values,但仍然很难理解何时应该使用值方法接收器而不是指针方法接收器在结构体上定义方法。换句话说,什么时候会优先选择这种方式:

type ByteSlice []byte

func (slice ByteSlice) Append(data []byte) []byte {
}

而不是这种方式:

func (p *ByteSlice) Append(data []byte) {
    slice := *p
    *p = slice
}
英文:

I've read a Tour of Go and Effective Go, http://golang.org/doc/effective_go.html#pointers_vs_values, but still have a difficult time understanding when you would define a method on a struct using a value method receiver instead of a pointer method receiver. In other words, when would this:

type ByteSlice []byte

func (slice ByteSlice) Append(data []byte) []byte {
}

be preferable over this?

func (p *ByteSlice) Append(data []byte) {
    slice := *p
    *p = slice
}

答案1

得分: 4

切片是一个地方,一开始并不总是很明显。切片头部很小,所以复制它是廉价的,并且底层数组通过指针引用,因此您可以使用值接收器来操作切片的内容。您可以在sort包中看到这一点,可排序类型的方法是在没有指针的情况下定义的。

只有在需要操作切片头部(即更改长度或容量)时,才需要使用切片的指针。对于一个Append方法,您会想要:

func (p *ByteSlice) Append(data []byte) {
    *p = append(*p, data...)
}
英文:

Slices are one place where it's not always obvious at first. The Slice header is small, so copying it is cheap, and the underlying array is referenced via a pointer, so you can manipulate the contents of a slice with a value receiver. You can see this in the sort package, where the methods for the sortable types are defined without pointers.

The only time you need to use a pointer with a slice, is if you're going to manipulate the slice header, which means changing the length or capacity. For an Append method, you would want:

func (p *ByteSlice) Append(data []byte) {
    *p = append(*p, data...)
}

答案2

得分: 2

关于这个问题,有一个常见问题解答:

> 首先,也是最重要的,方法是否需要修改接收者?如果需要修改,接收者必须是指针。
>
> ...
>
> 其次,需要考虑效率。如果接收者是一个大的结构体,比如一个大的结构体,使用指针接收者会更加高效。

英文:

There is an FAQ entry on that matter:

> First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer.
>
> ...
>
> Second is the consideration of efficiency. If the receiver is large, a big struct for instance, it will be much cheaper to use a pointer receiver.

huangapple
  • 本文由 发表于 2014年7月26日 00:40:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/24960496.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定