I am quite new to go, and quite confused about the receiver idea in Go. It is the exercise from A tour of Go.
Question body:
Remember the picture generator you wrote earlier? Let's write another one, but this time it will return an implementation of image.Image instead of a slice of data.
Define your own Image type, implement the necessary methods, and call pic.ShowImage.
Bounds should return a image.Rectangle, like image.Rect(0, 0, w, h).
ColorModel should return color.RGBAModel.
At should return a color; the value v in the last picture generator corresponds to color.RGBA{v, v, 255, 255} in this one.
Here is my code:
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)
}
And it will report a compile error:
command-line-arguments ./compile110.go:26: cannot use m (type Image) as type image.Image in argument to pic.ShowImage: Image does not implement image.Image (At method has pointer receiver)
My understanding is that for receivers of methods, it is alright to set them as either pointers or values. However, when I set all the "*Image" to "Image", the errors go away.
Can someone help me with this?
The answers provided below are sufficient for the question I raised. However, it seems that the pointer and value receivers thingy can be a bit more complicated.
From Effective Go:
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.
Hope this will help some of you as well.