【问题标题】:Pointer receiver and value receiver in Exercise:Image练习中的指针接收器和值接收器:Image
【发布时间】:2016-09-22 11:03:45
【问题描述】:

我还是个新手,对 Go 中的接收器想法很困惑。这是 A tour of Go 中的练习。

问题正文:

还记得你之前写的图片生成器吗?我们再写一个 一个,但这次它会返回一个 image.Image 的实现 而不是一片数据。

定义自己的Image类型,实现必要的方法,调用 pic.ShowImage.

Bounds 应该返回一个 image.Rectangle,比如 image.Rect(0, 0, w, h)。

ColorModel 应该返回 color.RGBAModel。

At 应该返回一个颜色;最后一张图片生成器中的值 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)
}

而且会报编译错误:

command-line-arguments ./compile110.go:26: 不能在 pic.ShowImage 的参数中使用 m(类型 Image)作为类型 image.Image:Image 没有实现 image.Image(At 方法有指针接收器)

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

有人可以帮我解决这个问题吗?


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

从有效围棋:

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

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

【问题讨论】:

  • 你为什么还要给这些函数接收器?你不使用它们。我觉得您正在尝试制作interface
  • 这是问题的要求。我怀疑 pic.ShowImage() 正在为界面图像调用这些方法。

标签: go


【解决方案1】:

当您在 Go 中使用接口时,您需要确保您使用的实例实现了该接口。在 Go-Tour 示例问题中,Image 不满足 image.Image 接口,只有 &Image 满足。

因此,您需要更改方法签名以获取值接收器,这将使Image 工作,或者将&Image 传递给pic.ShowImage 函数,因为指向Image 的指针确实实现了接口。

【讨论】:

    【解决方案2】:

    有两种方法可以解决此问题。

    一种方法是使用

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

    另一种方法是使用构造函数

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

    【讨论】:

      猜你喜欢
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 2018-01-20
      • 2018-10-14
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      相关资源
      最近更新 更多