2017-09-04 3 views
0

私はそうのようなバイナリツリーのNodeクラスを持っている:ジェネリック関数内スウィフト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.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 ||` 

私はなぜコンパイラがT値がEquatableているか、なぜそれがleftNodeTnodeTと同じタイプであることを考えていない理由を知っていないようだか分かりません。

コード:予想通り

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

Comparable'。 – Alexander

+0

私は 'Equatable'と' Comparable'を混同していると本当に馬鹿げていると感じます。ありがとうございました! – richy

+1

実際に必要なのは 'Comparable'プロトコルです。 'Equatable'プロトコルは、適合のために等価(' == ')関数の実装だけを必要とします。比較関数( '<'など)は 'Comparable'プロトコルによってのみ実装されることが保証されています。 –

答えて

0

一般的なケースでは、2つのNodeオブジェクトは比較できません。それは、それらが見つかったツリーの種類に依存します。たとえば、ノードがバイナリツリーの有効なメンバーに制限されている場合は意味がありますが、そうではありません。

幸いにも、あなたがComparableするNodeを必要としない、あなただけのComparableするそのvalueために必要なことができます:あなた `Node` ISNので、あなたの例 'C'を可能にすることはできません

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> { 
    //... 
} 

コードする必要があります:コンパイラは値がIntのです知っているので、

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

let c = a.value > b.value 

は、作業する必要があります。しかし、この関数では、入力値はわかりません。

関連する問題