[英]How to make a protocol extend another protocol and provide default implementation for it in Swift?
我有一个 BinarySearchTree 协议,并希望它的所有实现都符合 Sequence 协议。 由于 traverse 方法足以进行迭代,因此我想为 Sequence 所需的 makeIterator 方法提供一个默认实现,以便 BinarySearchTree 的任何实现都可以迭代,而无需进一步执行任何操作。 但是编译器给出了两个错误:
我为 LinkedList 做了类似的事情,并且效果很好。
这里有什么问题?
protocol BinarySearchTree: Sequence where Element == (Key, Value) {
associatedtype Key: Comparable
associatedtype Value
func insert(key: Key, value: Value)
func remove(key: Key) -> Value?
func find(key: Key) -> Value?
func findPredecessor(key: Key) -> (Key, Value)?
func findSuccessor(key: Key) -> (Key, Value)?
func min() -> (Key, Value)?
func max() -> (Key, Value)?
func removeMin() -> (Key, Value)?
func removeMax() -> (Key, Value)?
func traverse() -> AnySequence<(Key, Value)>
}
extension BinarySearchTree {
func makeIterator() -> AnyIterator<(Self.Key, Self.Value)> {
return traverse().makeIterator()
}
}
fileprivate class BSTNode<Key:Comparable, Value> {
let key: Key
let value: Value
var left: BSTNode<Key, Value>?
var right: BSTNode<Key, Value>?
unowned var parent: BSTNode<Key, Value>?
var isLeaf: Bool {
left == nil && right == nil
}
init(key: Key, value: Value){
self.key = key
self.value = value
}
func toTuple() -> (Key, Value) {
return (self.key, self.value)
}
func min() -> BSTNode {
guard let left = left else { return self }
return left.min()
}
func max() -> BSTNode {
guard let right = right else { return self }
return right.max()
}
func find(key: Key) -> BSTNode? {
if key == self.key {
return self
}
if key < self.key {
guard let left = left else { return nil }
return left.find(key: key)
}
guard let right = right else { return nil }
return right.find(key: key)
}
func findPredecessor() -> BSTNode? {
if let left = left { return left.max() }
var current = self
while let parent = current.parent {
if current === parent.right {
return parent
}
current = parent
}
return nil
}
func findSuccessor() -> BSTNode? {
if let right = right { return right.min() }
var current = self
while let parent = current.parent {
if current === parent.left {
return parent
}
current = parent
}
return nil
}
func insert(key: Key, value: Value) -> BSTNode {
if key <= self.key {
if let left = left {
return left.insert(key: key, value: value)
} else {
left = BSTNode(key: key, value: value)
left!.parent = self
return left!
}
} else {
if let right = right {
return right.insert(key: key, value: value)
} else {
right = BSTNode(key: key, value: value)
right!.parent = self
return right!
}
}
}
func delete() {
if isLeaf {
promoteChild(nil)
return
}
if left == nil {
promoteChild(right)
right = nil
return
}
if right == nil {
promoteChild(left)
left = nil
return
}
let successor = right!.min()
assert(successor.parent != nil)
successor.left = left
if successor.parent === self {
promoteChild(successor)
} else {
let successorsParent = successor.parent!
promoteChild(successor)
// successor must be left child unless it is right child of self
successorsParent.left = nil
successor.max().right = self.right
}
left = nil
right = nil
}
private func promoteChild(_ child: BSTNode?) {
guard let parent = parent else { return }
child?.parent = parent
if parent.left === self {
parent.left = child
} else {
parent.right = child
}
self.parent = nil
}
}
class BinarySearchTreeImp<Key: Comparable, Value> : BinarySearchTree {
private var root: BSTNode<Key, Value>?
init(){}
func min() -> (Key, Value)? {
return root?.min().toTuple()
}
func max() -> (Key, Value)? {
return root?.max().toTuple()
}
func find(key: Key) -> Value? {
return root?.find(key: key)?.value
}
func findPredecessor(key: Key) -> (Key, Value)? {
return root?.find(key: key)?.findPredecessor()?.toTuple()
}
func findSuccessor(key: Key) -> (Key, Value)? {
return root?.find(key: key)?.findSuccessor()?.toTuple()
}
func insert(key: Key, value: Value) {
if let root = root {
root.insert(key: key, value: value)
} else {
root = BSTNode(key: key, value: value)
}
}
func remove(key: Key) -> Value? {
guard let node = root?.find(key: key) else { return nil }
let result = node.value
node.delete()
return result
}
func removeMin() -> (Key, Value)? {
guard let node = root?.min() else {
return nil
}
node.delete()
return node.toTuple()
}
func removeMax() -> (Key, Value)? {
guard let node = root?.max() else {
return nil
}
node.delete()
return node.toTuple()
}
func traverse() -> AnySequence<(Key, Value)> {
return AnySequence { () -> AnyIterator<(Key, Value)> in
var currentNode: BSTNode<Key, Value>? = self.root?.min()
return AnyIterator {
let result = currentNode?.toTuple()
currentNode = currentNode?.findSuccessor()
return result
}
}
}
}
问题来自min()
/ max()
要求:
func min() -> (Key, Value)?
func max() -> (Key, Value)?
如果您将它们注释掉,代码就会生成。
Sequence
还公开了这两个函数,但是它们是仅当Element
是Comparable
时才可用的扩展的一部分,这不是您的情况,因此不确定为什么它会混淆编译器。
另一种解决方法是让BinarySearchTreeImp
声明Iterator
类型别名:
typealias Iterator = AnyIterator<(Key, Value)>
,这也会使编译器静音,但是对于未来的一致性尚不清楚是否需要添加它来解决半模糊的编译器错误消息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.