简体   繁体   English

为什么 Go 图像 package 剪切+粘贴在像素上循环?

[英]Why does the Go image package cut+paste looping over pixels?

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.如果您在此处查看图像 package http://golang.org/src/pkg/image/image.go您可以看到相同的实现,仅在像素中不同()逻辑。

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?类型系统是否存在一些限制(我看不到)会使多态 [was: generic] 方法变得困难?

[edit] The kind of solution I was thinking of (which does not need generics in the Java sense) would be like: [编辑]我正在考虑的那种解决方案(在 Java 意义上不需要 generics)就像:


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.).但我在编译时遇到了麻烦(对于 Go 来说仍然很新——它将使用图像编译,但不会使用图像指针编译。)。

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?). (你需要有 function 内联,但是不会有任何类型检查被拉出循环吗?)。 Also, I now realise I shouldn't have used the word "generic" earlier - I meant it only in a generic (ha) way.另外,我现在意识到我不应该早先使用“通用”这个词——我的意思只是以通用(ha)的方式。

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:例如,RGBA.Opaque 和 NRGBA.Opaque 的主体是相同的,因此您会认为它们可以分解为第三个 function ,其签名如下:

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

You'd like to call that function this way:您想这样称呼 function :

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. p.Pix 无法转换为 []Color,因为这些类型具有不同的内存表示,并且规范禁止它。 We could allocate a new slice, convert each individual element of p.Pix, and pass that, but that would be very inefficient.我们可以分配一个新的切片,转换 p.Pix 的每个单独元素,然后传递它,但这会非常低效。

Observe that RGBAColor and NRGBAColor have the exact same structure.观察 RGBAColor 和 NRGBAColor 具有完全相同的结构。 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:也许我们可以只考虑这两种类型的 function,因为像素切片的内存表示完全相同:

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.这似乎是 generics 会派上用场的领域,但是 Go 中的 generics 还没有解决方案。

Why does Go not have generic types?为什么 Go 没有泛型类型?

Generics may well be added at some point. Generics 可能会在某个时候添加。 We don't feel an urgency for them, although we understand some programmers do.我们不觉得他们有紧迫感,尽管我们知道一些程序员会这样做。

Generics are convenient but they come at a cost in complexity in the type system and run-time. Generics 很方便,但它们的代价是类型系统和运行时的复杂性。 We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it.尽管我们仍在继续思考,但我们还没有找到一种能够提供与复杂性成比例的价值的设计。 Meanwhile, Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly.同时,Go 的内置映射和切片,以及使用空接口构造容器(通过显式拆箱)的能力,意味着在许多情况下,即使不太顺利,也可以编写 generics 将启用的代码。

This remains an open issue.这仍然是一个悬而未决的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM