2016-05-25 26 views
1

私はかなり新しく、Goのレシーバーのアイデアについてはかなり混乱しています。 Goのツアーからの運動です。練習のポインタレシーバーとバリューレシーバー:画像

質問本体:

package main 

import "golang.org/x/tour/pic" 
import "image" 
import "image/color" 


type Image struct{} 

func (img *Image) Bounds() image.Rectangle{ 
    w := 100 
    h := 100 
    return image.Rect(0,0,w,h) 
} 

func (img *Image) ColorModel() color.Model{ 
    return color.RGBAModel 
} 

func (img *Image) At(x int, y int) color.Color{ 
    return color.RGBA{uint8(x^y), uint8(y/2), 255,255} 
} 

func main() { 
    m := Image{} 
    pic.ShowImage(m) 
} 

そして、それは、コンパイルエラーが報告されます:

​​

ここでは私のコードがある

コマンドライン引数を./compile110.go:26 :タイプイメージとしてm(タイプImage)を使用することはできません。pic.ShowImageの引数にイメージ:イメージはimage.Imageを実装していません(メソッドにはポインタレシーバがあります)


私の理解では、メソッドの受信者にとっては、ポインタまたは値として設定することが大切です。しかし、すべての "* Image"を "Image"に設定すると、エラーは消えます。

誰かがこれを手伝ってくれますか?


私が提起した質問には以下の回答で十分です。しかし、ポインタとバリューレシーバはちょっと複雑に思えます。効果的な移動から

The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers. This rule arises because pointer methods can modify the receiver; invoking them on a value would cause the method to receive a copy of the value, so any modifications would be discarded. The language therefore disallows this mistake. There is a handy exception, though. When the value is addressable, the language takes care of the common case of invoking a pointer method on a value by inserting the address operator automatically.

が、これは同様にあなたのいくつかを助けることを願っています。

+1

なぜこれらの機能受信機を提供していますか?あなたはそれらを使用しません。私はあなたが 'インターフェース 'を作っているように感じています。 – IanAuld

+0

それは質問の要件です。私は、pic.ShowImage()がこれらのメソッドをインターフェイスイメージとして呼び出すと考えています。 –

答えて

2

を使用している、あなたはそのインターフェイス実装を使用しているインスタンスを確認する必要があります。 Go-Tourのサンプル問題では、Imageimage.Imageインターフェイスを満たしておらず、&Imageだけを満たしています。あなたがImage作業を行います値の受信機を取るために、あなたのメソッドのシグネチャを変更、またはImageへのポインタがインタフェースを実装していますので、pic.ShowImage関数に&Imageを渡すのいずれか必要がある。このよう

2

これを修正するには2通りの方法があります。あなたが移動中のインタフェースを使用する場合

一つの方法は、

func main() { 
    m := &Image{} 
    pic.ShowImage(m) 
} 

を使用している他の方法は、コンストラクタに

func NewImage() *Image { 
    return &Image{} 
} 

func main() { 
    m := NewImage() 
    pic.ShowImage(m) 
}