如何解决通用类型在不透明类型的帮助下符合Sequence:一些IteratorProtocol
protocol TreeNode: AnyObject {
associatedtype T
var value: T { get set }
var children: [Self] { get }
init(_ value: T)
}
protocol Tree: Sequence {
associatedtype Node: TreeNode
var root: Node? { get set }
}
extension Tree {
typealias T = Node.T
func makeIterator() -> some IteratorProtocol {
BFSIterator(startFrom: root)
}
}
这可以编译并且看起来很有希望。
但是随后突然在单元测试行let sum = tree.reduce(0,+)
中导致编译错误:
无法将类型'(Int)-> Int'的值转换为预期的参数类型 '((Int,(某些IteratorProtocol).Element)抛出-> Int'
为什么编译器无法弄清楚(some IteratorProtocol).Element
确实是Int
?以及如何帮助呢?
请注意,如果我使用“旧方法”(没有不透明类型): func makeIterator()-> BFSIterator { 一切都能编译并完美运行。
更新:
struct BFSIterator<Node: TreeNode>: IteratorProtocol {
private var queue: Queue<Node> = []
init(startFrom root: Node?) {
root.map { queue.push($0) }
}
mutating func next() -> Node.T? {
guard let current = queue.pop() else { return nil }
queue.push(contentsOf: current.children)
return current.value
}
}
解决方法
之所以发生这种情况,是因为当前的Swift(5.2)中无法为不透明的返回值指定关联的类型。因此,some IteratorProtocol
不足以使编译器确定next()
方法应返回哪种值。
语言的这种局限性迫使您在实际使用序列时明确声明迭代器类型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。