2013-02-17 50 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