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

泛型函数内的Swift可等式泛型类型比较,swift,generics,equatable,Swift,Generics,Equatable,我有一个用于二叉树的节点类,如下所示: 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.le

我有一个用于二叉树的
节点
类,如下所示:

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
    }
}
这很好,
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)
给出了预期的错误

进一步研究,它与函数无关,因为当我尝试代码时:

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

我得到了同样的错误

多亏了Alexander,我把我的
相等的
可比的
搞混了!节点应该是

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

必须正常工作,因为编译器知道值是
Int
s。但是在函数中,输入值是未知的。

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

幸运的是,您不需要
节点
具有可比性
,只需要它的
具有可比性:

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
    }
}
类节点{
let值:T
左:节点?
右转:节点?
init(值:T,左:节点?=nil,右:节点?=nil){
自我价值=价值
self.left=左
self.right=right
}
}
扩展节点:equalable{
静态函数==(左:节点,右:节点)->Bool{
返回lhs.value==rhs.value
&&左侧==右侧左侧
&&lhs.right==rhs.right
}
}
扩展节点{
func isBinarySubTree()->Bool{
返回left.map{$0.value
你的例子
c
不可能,因为你的
节点
不可比
我觉得把我的
可比性
可比性
混在一起很傻。非常感谢。您实际需要的是
可比较的
协议。
equalable
协议只需要实现equality(
=
)函数即可实现一致性。比较函数(例如,
@richy)在这样的任意树中,它的可比性实际上没有意义。您应该访问
并比较它们
let x = Node(value: 3, left: Node(value: 8) , right: nil)
let y = x.value < x.left!.value
class Node<T: Comparable> {
    //...
}
let a = Node(value: 8)
let b = Node(value: 7)

let c = a.value > b.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
    }
}