16

==Swift 3 の基本クラスとそのサブクラスに演算子 (from )を実装しようとしています。すべてのクラスは Swift でのみ使用されるため、プロトコルEquatableを関与させたくありません。NSObjectNSCopying

基本クラスとサブクラスから始めました。

class Base {
    var x : Int
}

class Subclass : Base {
    var y : String
}

Equatableここで、 と==演算子をに追加したいと思いましたBase。十分に単純に思えます。==ドキュメントからオペレーターの署名をコピーします。

class Base : Equatable {
    var x : Int

    static func == (lhs: Base, rhs: Base) -> Bool {
        return lhs.x == rhs.x
    }
}

ここまでは順調ですね。サブクラスの場合:

class Subclass : Base {
    static override func == (lhs: Base, rhs: Base) -> Bool {
        return true
    }
}

しかし、これはエラーになります:

演算子関数は「最終」演算子関数をオーバーライドします

わかった。いくつかの調査(まだSwift 3を学習中)の後、型メソッドをオーバーライドできることを示すために をstatic置き換えることができることを学びました。class

だから私は in に変更しようとしstaticます:classBase

class Base : Equatable {
    var x : Int

    class func == (lhs: Base, rhs: Base) -> Bool {
        return lhs.x == rhs.x
    }
}

しかし、それは新しいエラーになります:

非最終クラス「ベース」で宣言された演算子「==」は「最終」でなければなりません

うーん。これは、必要以上に複雑です。

基本クラスとサブクラスでEquatableプロトコルと演算子を適切に実装するにはどうすればよいですか?==

4

4 に答える 4

18

多くの調査といくつかの試行錯誤の後、私は最終的に実用的な解決策を思いつきました. 最初のステップは、==オペレーターをクラス内からグローバル スコープに移動することでした。staticこれにより、およびに関するエラーが修正されましたfinal

基本クラスの場合、これは次のようになりました。

func == (lhs: Base, rhs: Base) -> Bool {
    return lhs.x == rhs.x
}

class Base : Equatable {
    var x : Int
}

サブクラスの場合:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
    return true
}

class Subclass : Base {
    var y : String
}

残っている唯一の部分は、サブクラス==の演算子から基本クラスの演算子を呼び出す方法を理解することです。==これにより、最終的な解決策が得られました。

func == (lhs: Subclass, rhs: Subclass) -> Bool {
    if lhs.y == rhs.y {
        if lhs as Base == rhs as Base {
            return true
        }
    }

    return false
}

その最初のifステートメント==は、基本クラスの演算子への呼び出しになります。


最終的な解決策:

Base.swift:

func == (lhs: Base, rhs: Base) -> Bool {
    return lhs.x == rhs.x
}

class Base : Equatable {
    var x : Int
}

Subclass.swift:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
    if lhs.y == rhs.y {
        if lhs as Base == rhs as Base {
            return true
        }
    }

    return false
}

class Subclass : Base {
    var y : String
}
于 2016-10-07T05:08:10.870 に答える
6

他の答えに続いて、私はこれを思いつきました:

class Base : Equatable {
    var x : Int
    static func == (lhs: Base, rhs: Base) -> Bool {
        return lhs.x == rhs.x
    }
}

class Subclass : Base {
    var y : String
    static func == (lhs: Subclass, rhs: Subclass) -> Bool {
        return lhs.y == rhs.y && (lhs as Base) == (rhs as Base)
    }
}
于 2019-01-13T14:54:41.367 に答える