我很陌生,对Go中的接收者想法感到很困惑。这是来自Go之旅的练习。
问题机构:
还记得你之前写过的图片生成器吗?我们写另一个 一,但这次它将返回image.Image的实现 而不是一片数据。
定义您自己的Image类型,实现必要的方法并调用 pic.ShowImage。
Bounds应返回一个image.Rectangle,如image.Rect(0,0,w,h)。
ColorModel应返回color.RGBAModel。
应该返回一个颜色;最后一个图片生成器中的值v 对应于此颜色.RGBA {v,v,255,255}。
这是我的代码:
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)
}
它将报告编译错误:
我的理解是,对于方法的接收者,可以将它们设置为指针或值。但是,当我将所有“* Image”设置为“Image”时,错误就会消失。
有人可以帮我这个吗?
下面提供的答案足以解决我提出的问题。但是,似乎指针和值接收器可能有点复杂。
从Effective Go开始:
关于接收器的指针与值的规则是值方法 可以在指针和值上调用,但指针方法只能是 在指针上调用。出现这个规则是因为指针方法可以 修改接收器;在值上调用它们会导致该方法 收到价值的副本,所以任何修改都是 丢弃。因此,该语言不允许这种错误。有一个 但是,方便的例外。当值可寻址时,语言 负责处理对值调用指针方法的常见情况 通过自动插入地址运算符。
希望这对你们中的一些人也有帮助。
答案 0 :(得分:3)
在Go中使用接口时,您需要确保您使用的实例实现该接口。在Go-Tour示例问题中,Image
不满足image.Image
界面,只有&Image
。{/ p>
因此,您需要更改方法签名以使值接收器使Image
工作,或者将&Image
传递给pic.ShowImage
函数,因为指向{{1}的指针确实实现了接口。
答案 1 :(得分:2)
有两种方法可以解决这个问题。
一种方法是使用
func main() {
m := &Image{}
pic.ShowImage(m)
}
另一种方法是使用构造函数
func NewImage() *Image {
return &Image{}
}
func main() {
m := NewImage()
pic.ShowImage(m)
}