泛型类型在不透明类型的帮助下符合序列:一些 IteratorProtocol
Posted
技术标签:
【中文标题】泛型类型在不透明类型的帮助下符合序列:一些 IteratorProtocol【英文标题】:Generic type conforms to Sequence with help of opaque type: some IteratorProtocol 【发布时间】:2021-02-18 05:45:20 【问题描述】: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, (some IteratorProtocol).Element) throws -> 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
【问题讨论】:
什么是BFSIterator
?
@NewDev struct BFSIterator发生这种情况是因为当前的 Swift (5.2) 中无法为不透明的返回值指定关联类型。因此,some IteratorProtocol
不足以让编译器确定next()
方法应该返回什么样的值。
如果您想实际使用序列,语言的这种限制会强制您显式声明迭代器类型。
【讨论】:
以上是关于泛型类型在不透明类型的帮助下符合序列:一些 IteratorProtocol的主要内容,如果未能解决你的问题,请参考以下文章
如何在不知道项目泛型类型参数的情况下对作为泛型给出的列表进行浅表复制? [复制]
我如何在不使用Delphi约束的情况下确定泛型类型为nil?
c# 在不知道类型的情况下,如何判断并使用带泛型的扩展方法?