Coding style 为什么Go image软件包会剪切+;在像素上粘贴循环?

Coding style 为什么Go image软件包会剪切+;在像素上粘贴循环?,coding-style,types,go,standard-library,Coding Style,Types,Go,Standard Library,如果您查看这里的图像包,您可以看到每个图像的不透明()实现都做相同的事情,只是在像素特定的逻辑上有所不同 这有什么原因吗?任何通用解决方案的效率都会降低吗?这只是疏忽吗?类型系统是否存在一些限制(我看不到),这会使多态[was:generic]方法变得困难 [edit]我想到的解决方案(不需要Java意义上的泛型)如下: type ColorPredicate func(c image.Color) bool; func AllPixels (p *image.Image, q ColorP

如果您查看这里的图像包,您可以看到每个图像的不透明()实现都做相同的事情,只是在像素特定的逻辑上有所不同

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

[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
}

类型ColorPredicate func(c image.Color)bool;
func所有像素(p*image.image,q ColorPredicate)bool{
var r=p.Bounds()
如果r.Empty(){
返回真值
}
对于y:=r.Min.y;y
但我在编译它时遇到了麻烦(仍然很新,它将使用图像进行编译,但不使用图像指针!)

这太难优化了吗?(您需要有函数内联,但这样就不会从循环中拉出任何类型检查了吗?)。此外,我现在意识到我不应该早些时候使用“泛型”这个词——我的意思只是泛型(ha)

在某些情况下,很可能会添加泛型 指向我们不觉得有什么紧迫感 他们,虽然我们了解一些 程序员是这样做的

泛型是方便的,但它们来了 以牺牲类型的复杂性为代价 系统和运行时。我们还没有 找到了一个有价值的设计 与复杂性成比例, 尽管我们继续思考 信息技术同时,Go的内置地图和 切片,以及使用 要构造的空接口 容器(显式拆箱) 这意味着在许多情况下 编写与泛型相同的代码 如果不太顺利,将启用

这仍然是一个悬而未决的问题


类型系统有一个限制,它阻止了一个通用的解决方案(或者至少使它非常低效)

例如,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转换为[]颜色,因为这些类型具有不同的内存表示形式,并且规范禁止这种转换。我们可以分配一个新的切片,转换p.Pix的每个元素,并传递它,但这将是非常低效的

观察RGBAColor和NRGBACLOR具有完全相同的结构。也许我们可以只考虑这两种类型的函数,因为像素切片的内存表示完全相同:

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

func (p *NRGBA) Opaque() bool {
    return opaque([]RGBAColor(p.Pix), p.Stride, p.Rect)
}
唉,这也是不允许的。这似乎更多的是规范/语言问题,而不是技术问题。我相信这已经出现在邮件列表之前,但我找不到一个很好的讨论它


这似乎是泛型可以派上用场的一个领域,但在Go中还没有泛型的解决方案。

你能不能编写一个函数,它包含第二个函数,其中包含检查像素的逻辑?我已经用我想的解决方案扩展了我的问题-它不是编译,但这可能是一个单独的问题。(也许我误解了你的回答,但我认为你的问题在于以一种通用的方式处理数组;我的建议更像是折叠,使用接口多态性)。啊,是的,那会有用。效率会低一些,但如果没有基准测试,很难说效率有多高。代码中唯一需要更改的是将AllPixels的第一个参数设置为非指针。您几乎不想在Go中使用指向接口的指针。它们是轻量级的,可以按值传递。感谢您的回复-这是真的我很高兴知道我并没有完全迷失于此!有一个正确的答案;o)虽然我猜答案真的是“可能是效率”。我不应该用“通用”这个词。go确实通过duck类型具有某种多态性。这还不够吗?请参见我上面添加的示例。