Last updated on
Go 结构体方法接受者用值还是指针
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
接受者的表现和 Go 中传递参数一样,是值传递
考量点 「官方 FAQ 」
- 值传递的空间耗费
- 是否需要修改原值
- 一致性
- Next is consistency. If some of the methods of the type must have pointer receivers, the rest should too, so the method set is consistent regardless of how the type is used. See the section on method sets for details.
对于官网中提到的一致性,实际测试下来是都能相互调用的,值调用指针方法,指针调用值方法,Go 会自己帮忙做转化
Note
https://stackoverflow.com/questions/27775376/value-receiver-vs-pointer-receiver/27775558#27775558
The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers
Which is not true, as commented by Sart Simha
type String struct {
Value string
}
func (r String) ValueChange(newValue string) {
r.Value = newValue
}
func (r *String) PointerChange(newValue string) {
r.Value = newValue
}
func TestString(t *testing.T) {
s1 := String{Value: "123"}
s2 := String{"123"}
s1.ValueChange("456")
if s1.Value != "123" {
t.Fatal("failed")
}
s2.PointerChange("456")
if s2.Value != "456" {
t.Fatal("failed")
}
s3 := &String{"123"}
s3.ValueChange("456")
if s3.Value == "456" {
t.Fatal("failed")
}
s3.PointerChange("456")
if s3.Value != "456" {
t.Fatal("failed")
}
}