提问人:user14205680 提问时间:8/23/2021 更新时间:8/23/2021 访问量:153
Swift - 序列 - 为什么我不需要为 Element 和 Iterator 添加类型别名?
Swift - Sequence - Why I'm not required to add typealiases for Element and Iterator?
问:
我正在学习 Swift,不明白为什么我可以声明
class MultiSet<T: Hashable> : Swift.Sequence {
var data = [T]()
func makeIterator() -> Array<T>.Iterator {
return data.makeIterator()
}
}
那会起作用的。但是,如果我复制声明并写Sequence
class MultiSet<T: Hashable> : MySequence {
var data = [T]()
func makeIterator() -> Array<T>.Iterator {
return data.makeIterator()
}
}
public protocol MySequence {
associatedtype Element where Self.Element == Self.Iterator.Element
associatedtype Iterator : IteratorProtocol
func makeIterator() -> Self.Iterator
}
我遇到错误,需要显式写入协议存根:
typealias Element = <#type#>
typealias Iterator = <#type#>
它是如何自动推断的?
谢谢!
答:
这是因为您在声明中添加的约束只是一个约束,实际上并不能解析类型。associatedtype
为了能够解决 您需要在协议(或实现)中对该 .associatedtype
associatedtype
在您的示例中,您的实现仅“解析”:Iterator
associatedtype
public protocol MySequence {
func makeIterator() -> Self.Iterator
}
class MultiSet<T: Hashable> : Swift.Sequence {
func makeIterator() -> Array<T>.Iterator {
return data.makeIterator()
}
}
因为你在实现中“替换”了,所以 Swift 知道应该如何解决。但在这一点上仍然没有解决。Iterator
Array<T>.Iterator
Iterator
Element
注意:Xcode 确实在实现中要求同时提供 和 类型别名,但实际上是唯一一个。 如果添加
Element
Iterator
Element
typealias Element = T
其中修复了错误。
MultiSet
如果你想让 Swift 能够解析,你将需要同样类型的“引用”,无论是在你的实现中,还是在你的协议中直接使用扩展。Element
MultiSet
例如:
public protocol MySequence {
associatedtype Element where Self.Element == Self.Iterator.Element
associatedtype Iterator : IteratorProtocol
func makeIterator() -> Iterator
func foobar() -> Element? // added a reference to Element
}
extension MySequence {
func foobar() -> Iterator.Element? {
nil
}
}
struct MultiSet<T>: MySequence {
var data = [T]()
func makeIterator() -> Array<T>.Iterator {
return data.makeIterator()
}
}
这将允许 Swift 解析为 .Element
Iterator.Element
注意:您可以在没有扩展中默认实现的情况下进行 inside 定义。我用了这个例子,因为它是在里面完成的。
foobar
MultiSet
Sequence
如果你看一下实现(源代码),你会注意到函数(引用),有一个默认的实现(解析为Sequence
_customContainsEquatableElement
Element
Element
Iterator.Element
)
public protocol Sequence {
func _customContainsEquatableElement(
_ element: Element
) -> Bool?
}
// [...]
extension Sequence {
public func _customContainsEquatableElement(
_ element: Iterator.Element
) -> Bool? {
return nil
}
}
这就是为什么在实现时不必显式解析 ,它被隐式解析为 。Sequence
Element
Iterator.Element
评论
T
Element