coding-style - 为什么 Go 图像包剪切 + 粘贴循环像素?

标签 coding-style types go standard-library

如果你在这里查看图片包http://golang.org/src/pkg/image/image.go您可以看到,每个图像的 Opaque() 实现都做同样的事情,仅在特定于像素的逻辑上有所不同。

这是有原因的吗?任何通用解决方案的效率都会降低吗?这只是一个疏忽吗?类型系统是否有一些限制(我看不到)会使多态[是:泛型]方法变得困难?

[edit] 我想到的解决方案(不需要 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 来说仍然很新——它会用图像编译,但不能用图像指针编译!)。

这太难优化了吗? (你需要有函数内联,但是不会将任何类型检查从循环中拉出来吗?)。此外,我现在意识到我不应该早先使用“通用”这个词 - 我的意思只是以通用 (ha) 的方式。

最佳答案

类型系统存在限制,这阻碍了通用解决方案(或至少使其效率非常低)。

例如,RGBA.Opaque 和 NRGBA.Opaque 的主体是相同的,因此您认为可以将它们分解为具有如下签名的第三个函数:

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

您想这样调用该函数:

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

但是你不能。 p.Pix 无法转换为 []Color,因为这些类型具有不同的内存表示形式,而且规范禁止这样做。我们可以分配一个新的 slice ,转换 p.Pix 的每个单独元素,然后传递它,但那会非常低效。

观察 RGBAColor 和 NRGBAColor 具有完全相同的结构。也许我们可以分解出这两种类型的函数,因为像素 slice 的内存表示完全相同:

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

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

唉,这又是不允许的。这似乎更像是一个规范/语言问题,而不是技术问题。我确信这之前已经出现在邮件列表中,但我找不到关于它的良好讨论。

这似乎是泛型派上用场的领域,但 Go 中还没有针对泛型的解决方案。

关于coding-style - 为什么 Go 图像包剪切 + 粘贴循环像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6645329/

相关文章:

c++ - 根据模板变量类型执行不同的方法

c# - 为什么 IsAssignableFrom() 不适用于 int 和 double?

mongodb - 如何使用 mongo go 驱动程序而不是 Date(-62135596800000) 为日期字段分配空值

go - 如何检查一个值是否实现了一个接口(interface)

java - 在我的 Java Servlet 中使用私有(private)类有什么问题吗?

java - 编码实践 - 我应该使用哪种编码方法?

php - 在 PHP 编码标准中变量名应该采用驼峰式命名有什么原因吗?

c++ - #pragma once 与包括 guard ?

go - 在虚拟主机中设置一个简单的 go 服务器

sql - 如何在SQL Server中存储十进制值?