代码之家  ›  专栏  ›  技术社区  ›  richy

泛型函数内的Swift可等式泛型类型比较

  •  3
  • richy  · 技术社区  · 7 年前

    我有一个 Node 类为二叉树,如下所示:

    class Node<T: Equatable> {
        let value: T
        let left: Node<T>?
        let right: Node<T>?
    
        init(value: T, left: Node<T>? = nil, right: Node<T>? = nil) {
            self.value = value
            self.left = left
            self.right = right
        }
    }
    

    我可以这样测试公平性:

    let a = Node(value: 8)
    let b = Node(value: 7)
    
    let c = a.value > b.value
    

    这很好, c: true

    但当我编写一个使用节点均衡性的泛型函数时,我会出错:

    func isBinaryTree<T>(node: Node<T>) -> Bool {
        if let leftNode = node.left {
            guard leftNode.value < node.value else {
                return false
            }
            guard isBinaryTree(node: leftNode) else {
                return false
            }
        }
        if let rightNode = node.right {
            guard rightNode.value >= node.value else {
                return false
            }
            guard isBinaryTree(node: rightNode) else {
                return false
            }
        }
    
        return true
    }
    
    let result = isBinaryTree(node: root)
    

    error: binary operator '<' cannot be applied to two 'T' operands guard leftNode.value < node.value ||`
    

    T 值为 Equatable 或者为什么它不认为 leftNode 类型与 T node .

    代码:

    let d = Node(value: Float(3), left: Node(value: Int(8)) , right: nil)
    

    按预期给出错误。

    let x = Node(value: 3, left: Node(value: 8) , right: nil)
    let y = x.value < x.left!.value
    

    我也有同样的错误

    2 回复  |  直到 7 年前
        1
  •  5
  •   Alexander    7 年前

    在一般情况下,两个 Node 对象是不可比较的。这取决于在哪种树上找到它们。例如,如果节点仅被约束为二叉树的有效成员,这是有意义的,但事实并非如此。

    幸运的是,你不需要 Comparable value 成为 :

    class Node<T: Comparable> {
        let value: T
        let left: Node<T>?
        let right: Node<T>?
    
        init(value: T, left: Node<T>? = nil, right: Node<T>? = nil) {
            self.value = value
            self.left = left
            self.right = right
        }
    }
    
    extension Node: Equatable {
        static func == (lhs: Node, rhs: Node) -> Bool {
            return lhs.value == rhs.value
                && lhs.left == rhs.left
                && lhs.right == rhs.right
        }
    }
    
    extension Node {
        func isBinarySubTree() -> Bool {
            return left.map { $0.value < self.value } ?? true
                && right.map { self.value < $0.value } ?? true
                && left?.isBinaryTree() ?? true
                && right?.isBinaryTree() ?? true
        }
    }
    
        2
  •  1
  •   richy    7 年前

    多亏了亚历山大,我的 Equatable Comparable 搞砸了!节点应为

    class Node<T: Comparable> {
        //...
    }
    

    代码:

    let a = Node(value: 8)
    let b = Node(value: 7)
    
    let c = a.value > b.value
    

    Int s、 但在函数中,输入值未知。