swift - 为什么我的二元运算符不能应用于正确键入的操作数?

标签 swift generics binary-search-tree associated-types

我正在构建一个二叉搜索树,它将保存我事先不知道其类型的对象(我称它们为记录)。树将由 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'

据我所知,keyrecord.key 都是 KeyProtocol 的实例,应该可供比较运算符使用 <强>⊰

谁能解释一下?

最佳答案

您需要确保 KR.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 本身以确保 KR.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/

相关文章:

java - 为什么这种在 Java 数组中查找最大数组的通用方法无法编译?

c - 二分搜索实现(大多数代码结构问题,又名新手问题)

search - 如何在有序集合中找到元素的索引?

ios - 在 Collection View 中交换单元格时保持单元格旋转

ios - 如何为倒数计时器创建循环进度指示器

ios - SwiftUI使用 View 模型模式以两种不同方式打开 View

algorithm - BST 和 Splay 树中 1...n 键的插入操作的复杂度是多少?

ios - 应用重启时照片丢失并取消固定

c# - 枚举的基类

typescript - 重载函数的参数泛型不包含所有选项