2

Hashable プロトコルを実装するとき。次のように、同等のプロトコル関数をクラス外で定義する必要があります。以下の通り。

func ==(lhs: Swap, rhs: Swap) -> Bool {
    return (lhs.cookieA == rhs.cookieA && lhs.cookieB == rhs.cookieB) ||
        (lhs.cookieB == rhs.cookieA && lhs.cookieA == rhs.cookieB)
}

class Swap: Printable,Hashable {
    var cookieA: Cookie
    var cookieB: Cookie

    init(cookieA: Cookie, cookieB: Cookie) {
        self.cookieA = cookieA
        self.cookieB = cookieB
    }
    var hashValue: Int {
    return cookieA.hashValue ^ cookieB.hashValue
    }

    var description: String {
    return "swap \(cookieA) with \(cookieB)"
    }
}

私にとってはちょっと奇妙です。上記の例では、 func == はクラス Swap に属している必要があります。では、なぜ func == をクラス外で宣言する必要があるのでしょうか??

4

3 に答える 3

7

主な理由は、メソッドではなく関数であるためです。関数はクラスに依存しないため、クラス宣言内でスコープを設定しても意味がありません。

プロトコルは、メソッドを使用して設計することもできます。たとえば、obj1.isEqualTo(obj2)メソッドを使用することもできますが、関数はnil問題の影響を受けにくくなります。の場合、メソッドは失敗しますobj1nil

于 2014-07-18T08:02:09.917 に答える
1

演算子関数は、オーバーロードされる演算子と一致する関数名を持つグローバル関数として定義されます。関数は、ターゲット クラスまたは構造体のメソッドとしてではなく、グローバルに定義されるため、ターゲット クラスまたは構造体の既存のインスタンス間で中置演算子として使用できます。

この質問については、こちらのブログ投稿で詳しく回答しています。それが役に立てば幸い。

于 2016-05-17T13:37:23.210 に答える
1

私はそれをあまり読みません。シンプルな設計上の判断だと思います。はい、多くの言語では、演算子のオーバーロードは左側のオペランドのメソッドであり、それで問題ありませんが、演算子を関数として定義すると、おそらくもう少し柔軟性が得られるため、すべて関数にすることにしました。

于 2014-07-18T08:20:26.143 に答える