我有一个逐行输出像素的对象(就像旧电视那样)。该对象只是将字节写入二维数组。因此存在多条水平线,每条水平线具有多个像素。这些数字是固定的:有x个水平线,每个线y个像素。像素是红色,绿色,蓝色的结构。
我希望这个类的客户能够插入自己的对象来编写这些值,因为我希望这个代码在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
出现两个问题:
如何要求协议PixelLine在阵列中至少有1280个像素单位,并且协议OutputReceivable在阵列中至少有720个PixelLine元素?
我从a video学习,使用泛型可以帮助编译器生成最佳代码。有没有办法让我使用泛型来生成更高效的代码,然后使用普通协议作为一种类型?
答案 0 :(得分:0)
Swift中没有依赖类型。您不能直接要求Arrays具有最小尺寸。您可以做的是创建只能使用特定数据构建的新类型。所以在这种情况下,更好的模型是使PixelLine
成为结构而不是协议。然后,您可以拥有init?
,以确保在使用之前它是合法的。
围绕阵列的简单结构包装器在内存中是零成本,在分派中成本极低。如果您正在处理高性能系统,那么包装数组的结构是一个很好的起点。
struct PixelLine {
let pixels: [Pixel]
init?(pixels: [Pixel]) {
guard pixels.count >= 1280 else { return nil }
self.pixels = pixels
}
}
你可以像这样直接公开pixels
,或者你可以使PixelLine
成为一个集合(甚至只是一个序列),将其所需的方法转发给pixels
。