Chr*_*ood 3 generics swift swift-protocols protocol-extension swift3.2
我正在尝试编写符合集合协议的协议,它有一个associatedType - Object和一个属性对象.
protocol DDCDataSource: Collection
{
associatedtype Object
var object: Object {get set}
}
Run Code Online (Sandbox Code Playgroud)
我想为Object也符合Collection协议的情况添加一些默认功能,即直接返回Object对这些必需Collection属性和函数的实现.除了Collection对下标的要求外,它似乎都有效.
无法使用类型为"Self.Object.Index"的索引下标"Self.Object"类型的值
extension DDCDataSource where Object: Collection
{
typealias Index = Object.Index
var startIndex: Object.Index {
get {
return object.startIndex
}
}
var endIndex: Object.Index {
get {
return object.endIndex
}
}
subscript(position: Object.Index) -> Element
{
return object[position]
}
func index(after i: Object.Index) -> Object.Index {
return object.index(after: i)
}
}
Run Code Online (Sandbox Code Playgroud)
简答:将下标方法的返回类型更改为Object.Element
subscript(position: Object.Index) -> Object.Element {
return object[position]
}
Run Code Online (Sandbox Code Playgroud)
或添加类型别名(以与您对Index
类型类似的方式)
typealias Element = Object.Element
subscript(position: Object.Index) -> Element {
return object[position]
}
Run Code Online (Sandbox Code Playgroud)
这使得代码按预期编译和运行.
说明:该subscript
方法的Collection
声明为
subscript(position: Self.Index) -> Self.Element { get }
Run Code Online (Sandbox Code Playgroud)
在哪里Self.Index
和Self.Element
是相关类型的`集合.用你的代码
subscript(position: Object.Index) -> Element {
return object[position]
}
Run Code Online (Sandbox Code Playgroud)
编译器推断Self.Index
是Object.Index
,但是Self.Element
和之间没有关系Object.Element
(返回者object[position]
).如果添加显式强制转换,则错误会更明显:
subscript(position: Object.Index) -> Element {
return object[position] as Element
}
Run Code Online (Sandbox Code Playgroud)
现在编译器抱怨了
错误:'Self.Object.Element'不能转换为'Self.Element'; 你的意思是用'as!' 迫使低垂?
正确的解决办法是不强制投反而使编译器知道Self.Element
是Object.Element
,通过增加一个类型别名或通过改变返回类型
subscript(position: Object.Index) -> Object.Element {
return object[position]
}
Run Code Online (Sandbox Code Playgroud)
所以编译器推断 DDCDataSource.Element
是Object.Element
.
完整的自包含示例:( Swift 4,Xcode 9 beta 6)
(请注意,您可以省略get
只读计算属性的关键字.)
protocol DDCDataSource: Collection {
associatedtype Object
var object: Object { get set }
}
extension DDCDataSource where Object: Collection {
var startIndex: Object.Index {
return object.startIndex
}
var endIndex: Object.Index {
return object.endIndex
}
subscript(position: Object.Index) -> Object.Element {
return object[position]
}
func index(after i: Object.Index) -> Object.Index {
return object.index(after: i)
}
}
struct MyDataSource: DDCDataSource {
var object = [1, 2, 3]
}
let mds = MyDataSource()
print(mds[1]) // 2
for x in mds { print(x) } // 1 2 3
Run Code Online (Sandbox Code Playgroud)