我正在构建一个二叉搜索树,它将保存我事先不知道其类型的对象(我称它们为记录)。树将由 Key 排序,它是 Record 的一部分(再次键入未知)。所以我选择了泛型,符合协议(protocol)的记录要求它包含一个键,而键符合一个协议(protocol),该协议(protocol)要求它有一个对两个键进行排序的运算符。
infix operator ⊰: ComparisonPrecedence
public enum Comparator {
case matching
case leftTree
case rightTree
}
public protocol RecordProtocol {
associatedtype Key: KeyProtocol
var key: Key { get }
}
public protocol KeyProtocol {
static func ⊰(lhs: Self,rhs: Self) -> Comparator
}
public enum Tree<R: RecordProtocol, K: KeyProtocol> {
case empty
indirect case node(_ record: R,_ left: Tree<R,K>,_ right: Tree<R,K>)
public init() {
self = .empty
}
}
//This compiles perfectly fine
//Now I add a function to see if the tree contains a particular key
extension Tree {
public func contains(_ key: K) -> Bool {
switch self {
case .empty:
return false
case let .node(record, left, right):
switch key ⊰ record.key {
case .matching: return true
case .leftTree: return left.contains(key)
case .rightTree: return right.contains(key)
}
}
}
}
switch 语句编译失败并显示消息:
Binary operator '⊰' cannot be applied to operands of type 'K' and 'R.Key'
据我所知,key 和 record.key 都是 KeyProtocol 的实例,应该可供比较运算符使用 <强>⊰强>
谁能解释一下?
最佳答案
您需要确保 K
和 R.Key
是同一类型,因为您将自定义运算符定义为接受两个相同类型的输入参数。
extension Tree where K == R.Key {
public func contains(_ key: K) -> Bool {
switch self {
case .empty:
return false
case let .node(record, left, right):
switch key ⊰ record.key {
case .matching: return true
case .leftTree: return left.contains(key)
case .rightTree: return right.contains(key)
}
}
}
}
或者您可以修改 Tree
本身以确保 K
和 R.Key
始终是同一类型。
public enum Tree<R: RecordProtocol, K> where R.Key == K {
case empty
indirect case node(_ record: R,_ left: Tree<R,K>,_ right: Tree<R,K>)
public init() {
self = .empty
}
}
extension Tree {
public func contains(_ key: K) -> Bool {
switch self {
case .empty:
return false
case let .node(record, left, right):
switch key ⊰ record.key {
case .matching: return true
case .leftTree: return left.contains(key)
case .rightTree: return right.contains(key)
}
}
}
}
关于swift - 为什么我的二元运算符不能应用于正确键入的操作数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57055223/