值/指针接收者用哪个?
选择值或指针作为接收者
使用指针接收者的原因有二:
首先, 方法能够修改其接收者指向的值 。
其次,这样可以 避免在每次调用方法时复制该值 。若值的类型为大型结构体时,这样做会更加高效。
在本例中, Scale 和 Abs 接收者的类型为 *Vertex ,即便 Abs 并不需要修改其接收者。
通常来说,所有给定类型的方法都应该有值或指针接收者,但并 不应该二者混用(千万不要) 。(我们会在接下来几页中明白为什么。)
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Scale(f float64) { v.X = v.X * f v.Y = v.Y * f } func (v Vertex) Abs() float64 { return math.Sqrt(v.Xv.X + v.Yv.Y) } func main() { v := &Vertex{3, 4} fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs()) v.Scale(5) fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs()) }
27
1 package
main 2 3 import ( 4
"fmt" 5
"math" 6 ) 7 8 type
Vertex
struct { 9
X , Y
float64 10 } 11 12 func ( v
Vertex ) Scale ( f
float64 ) { 13
v . X
=
v . X
f 14
v . Y
=
v . Y
f 15 } 16 17 func ( v
Vertex ) Abs () float64 { 18
return
math . Sqrt ( v . X * v . X
v . Y * v . Y ) 19 } 20 21 func
main () { 22
v :
& Vertex { 3 , 4 } 23
fmt . Printf ( "Before scaling: %+v, Abs: %v\n" , v , v . Abs ()) 24
v . Scale ( 5 ) 25
fmt . Printf ( "After scaling: %+v, Abs: %v\n" , v , v . Abs ()) 26 } 27