调用一个带有指针接收器的方法时,使用对象而不是指向它的指针?

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

Calling a method with a pointer receiver by an object instead of a pointer to it?

问题

vVertex的一个对象,Scale是指向Vertex的指针的方法。那么为什么v.Scale(10)不是错误的,考虑到v不是指向Vertex对象的指针?谢谢。

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. type Vertex struct {
  7. X, Y float64
  8. }
  9. func (v Vertex) Abs() float64 {
  10. return math.Sqrt(v.X*v.X + v.Y*v.Y)
  11. }
  12. func (v *Vertex) Scale(f float64) {
  13. v.X = v.X * f
  14. v.Y = v.Y * f
  15. }
  16. func main() {
  17. v := Vertex{3, 4}
  18. v.Scale(10)
  19. fmt.Println(v.Abs())
  20. }
英文:

v is an object of Vertex, and Scale is a method for a pointer to Vertex. Then why is v.Scale(10) not wrong, given that v isn't a pointer to a Vertex object? Thanks.

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. type Vertex struct {
  7. X, Y float64
  8. }
  9. func (v Vertex) Abs() float64 {
  10. return math.Sqrt(v.X*v.X + v.Y*v.Y)
  11. }
  12. func (v *Vertex) Scale(f float64) {
  13. v.X = v.X * f
  14. v.Y = v.Y * f
  15. }
  16. func main() {
  17. v := Vertex{3, 4}
  18. v.Scale(10)
  19. fmt.Println(v.Abs())
  20. }

答案1

得分: 11

[规范:调用:]

如果方法集(类型的)x 包含 m,并且参数列表可以赋值给 m 的参数列表,那么方法调用 x.m() 是有效的。如果 x可寻址的,并且 &x 的方法集包含 mx.m() 就是 (&x).m() 的简写

编译器看到 Scale() 有一个指针接收器,并且 v 是可寻址的(因为它是一个局部变量),所以 v.Scale(10) 将被解释为 (&v).Scale(10)

这只是规范提供的许多便利之一,以使源代码保持简洁。

英文:

Spec: Calls:

> A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

The compiler sees that Scale() has a pointer receiver and also that v is addressable (as it is a local variable), so v.Scale(10) will be interpreted as (&v).Scale(10).

This is just one of the many conveniences the spec offers you so the source code can remain clean.

答案2

得分: 4

这是Go语言的自动解引用:

从https://golang.org/ref/spec#Method_values:

与选择器一样,使用指针引用值接收器的非接口方法将自动解引用该指针:pt.Mv 等同于 (*pt).Mv。

英文:

It's the Go automatic dereferencing:

From https://golang.org/ref/spec#Method_values:

>As with selectors, a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv.

huangapple
  • 本文由 发表于 2016年7月20日 20:32:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/38481420.html
匿名

发表评论

匿名网友

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

确定