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