2017-01-11 6 views
2

this questionによると、golangはtype-receiver methodpoint-receiver methodの両方を生成します。これは、以下のコードが正しく動作し、値が予期せず変更されることを意味します。ゴラン方式受信機

func (test *Test) modify() { 
    test.a++ 
} 

func main() { 
    test := Test{10} 
    fmt.Println(test) 
    test.modify() 
    fmt.Println(test) 
} 

私には受け入れ可能だと思います。しかし、これがインターフェイスと混ざり合うと、問題が起こります。

type Modifiable interface { 
    modify() 
} 

type Test struct { 
    a int 
} 

func (test *Test) modify() { 
    test.a++ 
} 

func main() { 
    test := Test{10} 
    fmt.Println(test) 
    test.modify() 
    fmt.Println(test) 

    var a Modifiable 

    a = test 
} 

それは言った:

Test does not implement Modifiable (modify method has pointer receiver) 

なぜこれが起こるのだろうか?

golangが実際にメソッド呼び出しを処理する方法は?

答えて

1

あなたが言った:

func (test *Test) modify() { 
    test.a++ 
} 

それは

func (test Test) modify() { 
     test.a++ 
} 

は、そのインターフェイスを意味するインタフェースModifiable

どこをテストするためにポインタ別名タイプ*Testによって実現されますタイプによって実装されますTest

結論:型とその型へのポインタは2種類あります。

+0

しかし、 'test'変数には' modify'というメソッドがあり、 'test.modify()'で呼び出すことができます。なぜ 'TestはModifiable'を実装していません。 – KIDJourney

+0

あなたは 'Test'ではなく' * Test'でインタフェースを実装しているからです。 'modify'メソッドは' Test'型ではなく '* Test'に対して定義されています。 'test.modify'を呼び出すとき、コンパイラは自動的に' * Test'を渡しますが、インタフェースの実装上の観点から明示的に '* Test'を使う必要があります – Ankur

+0

したがって、与えられたリンクの答えが間違っているので、' Test 'は生成されませんか?コンパイラが実際に行うことは、存在しない生成メソッドを呼び出す代わりに、ポインタを 'pointer-method'に渡すことです。 – KIDJourney

0

ポインタ受信機を持つメソッドを使用する場合は、つまり、アドレス値を渡す必要があります。ここ

は一例です:あなたはメソッドにポインタレシーバーを作成するたびインタフェースはアドレス値を受け入れます結論として

package main 

import "fmt" 

type Modifiable interface { 
    modify() 
} 

type Test struct { 
    a int 
} 

func (test *Test) modify() { 
    test.a++ 
} 

func main() { 
    test := Test{10} 
    fmt.Println(test) 
    test.modify() 
    fmt.Println(test) 

    var a Modifiable 

    a = &test 
    a.modify() 
    fmt.Println(a) 
} 

関連する問題