2013-02-17 49 views
3

今天在旅途中工作。我注意到我可以将结构文字传递给与指向结构的指针相关的方法,反之亦然。为什么这是允许的?方法接收器含糊不清

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} 
+0

参见[此](http://stackoverflow.com/q/13326099/ 720999)和[this](http://stackoverflow.com/q/13303254/720999)。 – kostix 2013-02-18 06:48:38

回答

5

参见Method sets

A型可具有与之相关联的方法集合(§Interface类型,§Method声明)。接口类型的方法集是它的接口。任何其他类型T的方法集由所有具有接收方类型T的方法组成。相应的指针类型* T的方法集合是所有具有接收方* T或T的方法的集合(即它还包含T)。其他规则适用于包含匿名字段的结构,如结构类型部分所述。任何其他类型都有一个空方法集。在方法集合中,每个方法必须具有唯一的方法名称。

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

编辑:

Calls参见:

一个方法调用XM()是有效的,如果(的类型)的方法集x包含m和可以分配的参数列表到m的参数列表。如果x是可寻址的并& X的方法集包含米,XM()是简写(& X).M():

+0

“任何其他类型的方法集合T由接收器类型为T的所有方法组成。”然而vLiteral.ScaleP(5)仍然编译。 – SChang 2013-02-17 22:56:24

+1

是的,这是正确的。查看更新后的答案。 – zzzz 2013-02-17 23:04:40

+1

这也在Go社区wiki [MethodSets](http://code.google.com/p/go-wiki/wiki/MethodSets)条目中有详细描述。 – 2013-02-18 17:36:59