我有一个协议,我想表达一个函数/变量可以返回特定类型的RandomAccessCollection
- 不一定是Array
,因为对于一个实现它使用库来访问数据。将库调用包装在符合RandomAccessCollection
的类中很容易,因此我不必构造一个Array
,这将涉及一堆额外的复制。
我正在尝试这样的事情:
protocol MyThing
{
var entries: RandomAccessCollection where Element: MyEntry { get }
}
..但是编译器并不喜欢这样;它似乎不喜欢那里有where
条款。
有没有办法做到这一点,这样我的协议的一个实现可以返回一个自定义RandomAccessCollection
- 一致的类,而另一个(比如一个用于测试的模拟版本)可以返回Array
?或者我是否需要为所有情况定义RandomAccessCollection
?
答案 0 :(得分:1)
Swift 4实现了以下进化建议:
允许您在协议中添加associatedtype
,可以通过where
子句使用更复杂的类型约束;不仅要向associatedtype
类型本身添加约束。例如,适用于您的示例:
// Swift 4 and beyond
protocol MyEntry { /* ... */ }
protocol MyThing {
associatedtype MyCollectionType: RandomAccessCollection
where MyCollectionType.Iterator.Element: MyEntry
var entries: MyCollectionType { get }
}
extension Int : MyEntry { /* ... */ }
// OK, Int conforms to MyEntry
struct Foo: MyThing {
internal var entries: [Int]
}
// Compile time error: Double doesn't conform to MyEntry
struct Bar: MyThing {
internal var entries: [Double]
}
// OK given that MyCustomRandomAccessCollection conforms
// to RandomAccessCollection
struct Baz: MyThing {
internal var entries: MyCustomRandomAccessCollection<Int>
}