为什么 Go 图像包会在像素上循环剪切和粘贴?
如果你在这里查看镜像包 http://golang.org/src/pkg/image /image.go 您可以看到每个图像的 Opaque() 实现都执行相同的操作,仅在特定于像素的逻辑上有所不同。
这是有原因的吗?任何通用解决方案的效率都会较低吗?这只是一个疏忽吗?类型系统是否存在一些限制(我看不到),这会使多态 [was: generic] 方法变得困难?
[编辑] 我正在考虑的解决方案(不需要 Java 意义上的泛型)是这样的:
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
}
但是我在编译它时遇到了麻烦(对于 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
类型系统有一个限制,它阻止了通用解决方案(或至少使其效率非常低)。
例如,RGBA.Opaque 和 NRGBA.Opaque 的主体是相同的,因此您会认为它们可以分解为具有如下签名的第三个函数:
您想这样调用该函数:
但是你不能。 p.Pix 无法转换为 []Color,因为这些类型具有不同的内存表示形式,并且规范禁止这样做。我们可以分配一个新的切片,转换 p.Pix 的每个单独元素,然后传递它,但这会非常低效。
观察 RGBAColor 和 NRGBAColor 具有完全相同的结构。也许我们可以只为这两种类型分解函数,因为像素切片的内存表示完全相同:
唉,这又是不允许的。这似乎更多是一个规范/语言问题,而不是技术问题。我确信这之前已经出现在邮件列表中,但我找不到对此的良好讨论。
这似乎是泛型可以派上用场的领域,但 Go 中还没有泛型的解决方案。
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:
You'd like to call that function this way:
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:
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.