drde3456 2011-07-11 02:56
浏览 29
已采纳

为什么Go图像包剪切+粘贴循环遍历像素?

If you look at the image package here http://golang.org/src/pkg/image/image.go you can see that the implementation of Opaque() for every image does the same thing, differing only in the pixel-specific logic.

Is there a reason for this? Would any general solution be less efficient? Is it just an oversight? Is there some limitation (I cannot see one) to the type system that would make a polymorphic [was: generic] approach difficult?

[edit] The kind of solution I was thinking of (which does not need generics in the Java sense) would be like:


type ColorPredicate func(c image.Color) bool;

func AllPixels (p *image.Image, q ColorPredicate) bool {
  var r = p.Bounds()
  if r.Empty() {
    return true
  }
  for y := r.Min.Y; y < r.Max.Y; y++ {
    for x := r.Min.X; x < r.Max.X; x++ {
      if ! q(p.At(x,y)) {
        return false
      }
    }
  }
  return true
}

but I am having trouble getting that to compile (still very new to Go - it will compile with an image, but not with an image pointer!).

Is that too hard to optimise? (you would need to have function inlining, but then wouldn't any type checking be pulled out of the loop?). Also, I now realise I shouldn't have used the word "generic" earlier - I meant it only in a generic (ha) way.

  • 写回答

2条回答 默认 最新

  • douerqu2319 2011-07-11 04:20
    关注

    There is a limitation to the type system which prevents a general solution (or at least makes it very inefficient).

    For example, the bodies of RGBA.Opaque and NRGBA.Opaque are identical, so you'd think that they could be factored out into a third function with a signature something like this:

    func opaque(pix []Color, stride int, rect Rectangle) bool
    

    You'd like to call that function this way:

    func (p *RGBA) Opaque() bool {
        return opaque([]Color(p.Pix), p.Stride, p.Rect)
    }
    

    But you can't. p.Pix can't be converted to []Color because those types have different in-memory representations and the spec forbids it. We could allocate a new slice, convert each individual element of p.Pix, and pass that, but that would be very inefficient.

    Observe that RGBAColor and NRGBAColor have the exact same structure. Maybe we could factor out the function for just those two types, since the in-memory representation of the pixel slices is exactly the same:

    func opaque(pix []RGBAColor, stride int, rect Rectangle) bool
    
    func (p *NRGBA) Opaque() bool {
        return opaque([]RGBAColor(p.Pix), p.Stride, p.Rect)
    }
    

    Alas, again this isn't allowed. This seems to be more of a spec/language issue than a technical one. I'm sure this has come up on the mailing list before, but I can't find a good discussion of it.

    This seems like an area where generics would come in handy, but there's no solution for generics in Go yet.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥15 MCNP里如何定义多个源?
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器