2017-09-04 157 views
0

内斯威夫特Equatable泛型类型的比较,我有一个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 
    } 
} 

的值需要equatable。

我可以测试出公平性这样的:

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 ||` 

我不知道为什么编译器似乎不知道为什么TEquatable或为什么它不认为在leftNodeT是相同类型Tnode

的代码:如预期

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

你的榜样'C'可以是不可能的,因为你的'Node' ISN '可比'。 – Alexander

+0

混淆了我的'Equatable'和'Comparable'我觉得很愚蠢。谢谢! – richy

+1

你实际需要的是“Comparable”协议。 “Equatable”协议只需要执行等式('==')函数来实现一致性。比较函数(如'<')只能保证由“Comparable”协议实现。 –

回答

0

在一般情况下,两个Node对象是不可比较的。它取决于它们被发现的树种类。例如,如果节点只被约束为二叉树的有效成员,那么这就很有意义,但事实并非如此。

幸运的是,你不需要NodeComparable,你可以只需要为它valueComparable

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 
    } 
} 
0

感谢亚历山大,我有我的EquatableComparable混合!节点应该是

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

代码:

let a = Node(value: 8) 
let b = Node(value: 7) 

let c = a.value > b.value 

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