我有一个将逐行输出像素的对象(就像旧电视一样)。这个对象只是将字节写入一个二维数组。所以有很多水平线,每一条都有很多像素。这些数字是固定的:有x条水平线,每行y个像素。像素是红、绿、蓝的结构。
我希望这个类的客户机插入他们自己的对象,可以将这些值写入其中,因为我希望这段代码2在Apple平台(CALayer存在的地方)上运行良好,但在其他平台(例如Linux,需要在没有CALayer的情况下完成渲染)上也运行良好。所以我想制定这样的协议:

struct Pixel
{
    var red: UInt8 = 0
    var green: UInt8 = 0
    var blue: UInt8 = 0
}
protocol PixelLine
{
    var pixels: [Pixel] { get }
}
protocol OutputReceivable
{
    var pixelLines: [PixelLine] { get }
}

这些协议在某些时候会被使用,比如
let pixelLineIndex = ... // max 719
let pixelIndex = ... // max 1279

// outputReceivable is an object that conforms to the OutputReceivable protocol
outputReceivale.pixelLines[pixelLineIndex][pixelIndex].red = 12
outputReceivale.pixelLines[pixelLineIndex][pixelIndex].green = 128
outputReceivale.pixelLines[pixelLineIndex][pixelIndex].blue = 66

出现两个问题:
如何要求协议像素线在阵列中至少有1280个像素单位,并且协议在阵列中至少输出720个像素线元素?
正如我从a video中学到的,使用泛型可以帮助编译器生成最佳代码。对于我来说,有没有一种方法可以使用泛型来生成比使用普通协议更高性能的代码呢?

最佳答案

Swift中没有依赖类型。不能直接要求数组具有最小大小。您可以做的是创建只能使用特定数据构造的新类型。因此,在这种情况下,更好的模型是使PixelLine成为一个结构,而不是一个协议。然后,您可以拥有一个init?来确保它在使用之前是合法的。
一个简单的数组结构包装器在内存中是零成本的,在调度中是极低成本的。如果要处理高性能系统,包装数组的结构是一个很好的起点。

struct PixelLine {
    let pixels: [Pixel]
    init?(pixels: [Pixel]) {
        guard pixels.count >= 1280 else { return nil }
        self.pixels = pixels
    }
}

您可以像这样直接公开pixels,也可以使PixelLine成为一个集合(甚至只是一个序列),将其所需的方法转发到pixels

关于arrays - 在Swift协议(protocol)中要求数组为最小大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38807908/

10-16 09:01