2017-09-04 109 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秒。但是在函數中,輸入值是未知的。