web-dev-qa-db-ja.com

Swiftの互換プロトコルを実装するにはどうすればよいですか?

Swiftで比較可能なプロトコルを使用するにはどうすればよいですか?宣言では、<、<=、> =の3つの演算を実装する必要があると述べています。私はそれらすべてをクラスに入れましたが、うまくいきません。また、3つすべてが必要ですか?なぜなら、それらすべてを単一のものから推定することが可能であるべきだからです。

36
Kametrixom

比較可能なプロトコルはEquatableプロトコルを拡張します->両方を実装します

Apple's Reference はApple(Comparable protocol reference内))の例です。これを実行する方法を確認できます。操作の実装をクラス内に配置しないでください、しかしむしろ外部/グローバルスコープにあります。また、<演算子、Comparableプロトコルおよび==Equatableプロトコルから。

正しい例:

class Person : Comparable {
    let name : String

    init(name : String) {
        self.name = name
    }
}

func < (lhs: Person, rhs: Person) -> Bool {
    return lhs.name < rhs.name
}

func == (lhs: Person, rhs: Person) -> Bool {
    return lhs.name == rhs.name
}

let paul = Person(name: "Paul")
let otherPaul = Person(name: "Paul")
let ben = Person(name: "Ben")

paul > otherPaul  // false
paul <= ben       // false
paul == otherPaul // true
60
Kametrixom

Swiftに対するKametrixomの回答の更新を以下に示します。

class Person : Comparable {

    let name : String

    init(name : String) {
        self.name = name
    }    

    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

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

Personクラスのインスタンスは、次のように関係演算子と比較できます。

let paul = Person(name: "Paul")
let otherPaul = Person(name: "Paul")
let ben = Person(name: "Ben")

print(paul > otherPaul)  // false
print(paul <= ben)       // false
print(paul == otherPaul) // true
4
Ekra

SwiftのComparableプロトコルを実装するには、最初にstatic func == (lhs: Self, rhs: Self) -> Boolを実装してEquatableプロトコルに準拠し、次にComparableに必要な唯一の関数static func < (lhs: Self, rhs: Self) -> Boolを実装する必要があります。

グローバルオペレーターオーバーロードを宣言する代わりに、構造体/クラス自体にプロトコル準拠メソッドを実装する必要があります。グローバルオペレーターオーバーロードはプロトコル適合性を満たしますが、構造体/クラスで意図された静的メソッドではなく、そのように宣言することはお勧めできません。

ドキュメンテーションの例を見ると、同じことがサンプルコードとして示されていることがわかります。

代わりに次のように書きます。

class Person: Comparable {
    let name: String

    init(name: String) {
        self.name = name
    }

    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

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

または、次のようにプロトコル宣言をクラス宣言から分離します。

class Person {
    let name: String

    init(name: String) {
        self.name = name
    }
}

extension Person: Comparable {
    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

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

これはおそらく本番レベルのコードに近いでしょう。

0
Schemetrical