You can only declare a method with a receiver whose type is defined in the same package as the method. You cannot declare a method with a receiver whose type is defined in another package (which includes the built-in types such as int). 不能定义原生类型的方法,可以通过 type 定义别名的方式来定义原生类型的方法。

receiver

带有值接收器的方法修改的是接收器的拷贝,带有指针接收器的方法才能修改该接收器本身的值。

Methods with pointer receivers can modify the value to which the receiver points (as Scale does here). Since methods often need to modify their receiver, pointer receivers are more common than value receivers.

1
2
3
4
5
6
7
8
9
10
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}

func main() {
v := Vertex{3, 4}
v.Scale(10)
fmt.Println(v.Abs())
}

function and methods

functions with a pointer argument must take a pointer,Functions that take a value argument must take a value.

1
2
3
var v Vertex
ScaleFunc(v, 5) // Compile error!
ScaleFunc(&v, 5) // OK

while methods with pointer receivers take either a value or a pointer as the receiver when they are called. Methods with value receivers take either a value or a pointer as the receiver when they are called

1
2
3
4
var v Vertex
v.Scale(5) // OK
p := &v
p.Scale(10) // OK

For the statement v.Scale(5), even though v is a value and not a pointer, the method with the pointer receiver is called automatically. That is, as a convenience, Go interprets the statement v.Scale(5) as (&v).Scale(5) since the Scale method has a pointer receiver.

Two reasons to use a pointer receiver.

The first is so that the method can modify the value that its receiver points to.

The second is to avoid copying the value on each method call. This can be more efficient if the receiver is a large struct, for example.