练习中的指针接收器和值接收器:图像

时间:2016-05-25 02:54:52

标签: go

我很陌生,对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)
}

它将报告编译错误:

命令行参数./compile110.go:26:不能使用m(类型Image)作为类型image.Image参数pic.ShowImage:Image不实现image.Image(At方法有指针接收器)< / H1>

我的理解是,对于方法的接收者,可以将它们设置为指针或值。但是,当我将所有“* Image”设置为“Image”时,错误就会消失。

有人可以帮我这个吗?

下面提供的答案足以解决我提出的问题。但是,似乎指针和值接收器可能有点复杂。

从Effective Go开始:

  

关于接收器的指针与值的规则是值方法   可以在指针和值上调用,但指针方法只能是   在指针上调用。出现这个规则是因为指针方法可以   修改接收器;在值上调用它们会导致该方法   收到价值的副本,所以任何修改都是   丢弃。因此,该语言不允许这种错误。有一个   但是,方便的例外。当值可寻址时,语言   负责处理对值调用指针方法的常见情况   通过自动插入地址运算符。

希望这对你们中的一些人也有帮助。

2 个答案:

答案 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)
}