2016-09-28 3 views
3

Goでは、Cat*Catは異なるタイプです。だから、なぜ彼らの名前は矛盾しますか?Goでポインターと非ポインターの受信者が同じ名前のメソッドを使用できないのはなぜですか?

type Animal interface { 
    GetName() string 
    SetName(string) 
} 

type Cat struct { 
    Name string 
} 

func (c *Cat) GetName() string { 
    return c.Name 
} 

func (c Cat) GetName() string { 
    return c.Name 
} 

func (c *Cat) SetName(s string) { 
    c.Name = s 
} 

Comiler応答:

方法は、再宣言:Cat.GetName

+1

どちらの方法の両方のバージョンを持つことはちょうど愚かであるので、それはバグや実装の意図的な部分です。それは、逆参照/アドレスがある場所です。ポインタやインスタンスを持っている場合は、他のインスタンスを簡単に取得できます。 – evanmcdonnal

+0

このインタフェースを実装する構造体を、このインタフェースを引数とする関数に渡す場合、どのメソッドが呼び出されるのか 'interface {GetName()string}'を考慮してください。 – mpm

答えて

6

Spec: Method sets:

は、任意の他のタイプTのメソッドセットが受信機と宣言されたすべての方法で構成されていタイプTと入力します。対応するポインタタイプ*Tのメソッドセットは、受信者*TまたはTで宣言されたすべてのメソッドのセット(つまり、Tのメソッドセットも含む)であるです。

あなたはレシーバタイプとしてCatと方法を持っているのであれば、その方法も*Catの方法セットの一部です。そのため、*Catは既にそのメソッドを持ち、同じ名前の "別の"ものを宣言しようとし、受信者タイプとして*Catが重複します。それを確認するために

、この例を参照してください。

type Cat struct{ Name string } 

func (c Cat) GetName() string { return c.Name } 

我々は唯一の非ポインタ受信機と1つのメソッドを宣言。私たちがチェックすると/対応*Cat種類の方法を印刷:

func main() { 
    var cp *Cat = &Cat{} // Pointer 
    t := reflect.TypeOf(cp) 
    for i := 0; i < t.NumMethod(); i++ { 
     fmt.Println(t.Method(i).Name) 
    } 
} 

出力は(Go Playground上でそれを試してみてください):

GetName 

タイプ*CatはすでにGetName方法があります。受信者が*Catの別のものを追加すると、上記のものと衝突します。公式のよくある質問から

関連質問:Why does Go not support overloading of methods and operators?

関連する問題