方法接收器的歧义

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

Method receivers ambiguity

问题

今天在进行Go之旅时,我注意到我可以将结构体字面量传递给与指向结构体的指针相关联的方法,反之亦然。为什么允许这样做?

package main

import (
    "fmt"
)

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) ScaleP(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func main() {
    v := &Vertex{3, 4}
    vLiteral := Vertex{3, 4}
    
    v.Scale(5)
    fmt.Println(v)
    
    v.ScaleP(5)
    fmt.Println(v)
    
    vLiteral.Scale(5)
    fmt.Println(vLiteral)
    
    vLiteral.ScaleP(5)
    fmt.Println(vLiteral)
}

输出:

&{3 4}
&{15 20}
{3 4}
{15 20}
英文:

Working on the go tour today. I noticed that I could pass struct literals to methods associated with pointer to structs, and vice versa. Why is this allowed?

package main

import (
    "fmt"
)

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) ScaleP(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func main() {
    v := &Vertex{3, 4}
    vLiteral := Vertex{3, 4}
    
    v.Scale(5)
    fmt.Println(v)
    
    v.ScaleP(5)
    fmt.Println(v)
    
    vLiteral.Scale(5)
    fmt.Println(vLiteral)
    
    vLiteral.ScaleP(5)
    fmt.Println(vLiteral)
}

Output:

&{3 4}
&{15 20}
{3 4}
{15 20}

答案1

得分: 5

参见方法集

一个类型可以有一个与之关联的方法集(§接口类型,§方法声明)。接口类型的方法集就是它自己。其他任何类型T的方法集都包含所有接收者类型为T的方法。相应指针类型T的方法集是所有接收者类型为T或T的方法的集合(也就是说,它还包含T的方法集)。对于包含匿名字段的结构体,还有其他规则,如在结构体类型的章节中所述。其他任何类型都有一个空的方法集。在方法集中,每个方法必须有一个唯一的方法名。

类型的方法集确定了该类型实现的接口以及可以使用该类型的接收者调用的方法。

编辑:

另请参见调用

如果(x的类型的)方法集包含m并且参数列表可以分配给m的参数列表,则方法调用x.m()是有效的。如果x是可寻址的并且&x的方法集包含m,则x.m()是(&x).m()的简写形式:

英文:

See Method sets:

> A type may have a method set associated with it (§Interface types, §Method declarations). The method set of an interface type is its interface. The method set of any other type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique method name.
>
> The method set of a type determines the interfaces that the type implements and the methods that can be called using a receiver of that type.

EDIT:

See also 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():

huangapple
  • 本文由 发表于 2013年2月18日 06:31:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/14926860.html
匿名

发表评论

匿名网友

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

确定