2017-06-25 1 views
2

Betrachten Sie diese Struktur:Kann ein vergleichbares Protokoll generisch sein?

struct Person : Comparable { 
    let name: String 
    let age: Int 
} 

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

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

Person structs jetzt nach Namen sortieren.

Aber was, wenn ich nach name oder age sortieren kann, gibt es eine Möglichkeit, die < func generic zu machen?

+0

Mögliches Duplikat von [https://stackoverflow.com/questions/25025618/generic-class-that-conforms-to-comparable-in-swift](https://stackoverflow.com/questions/25025618/generic- class-that-conforms-to-compare-in-swift) –

+0

Sah das schon, aber glaube nicht, dass es ein Duplikat ist. Bitte erläutern Sie, warum Sie es (neben dem Titel) denken. Vielen Dank. – Koen

+0

Wie entscheiden Sie zur Laufzeit, ob nach Name oder Alter sortiert werden soll? –

Antwort

1

Versuchen Sie folgendes:

struct Person : Comparable { 
    let name: String 
    let age: Int 
    let compareByAge: Bool 
} 

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

static func == (lhs: Person, rhs: Person) -> Bool { 
    if compareByAge { 
     return lhs.age == rhs.age 
    } 
    return lhs.name == rhs.name 
} 
+0

Das könnte funktionieren, aber wenn ich mehr Eigenschaften (lastName, Adresse, etc) habe, dann wird es eine Menge von if-else Code geben. Wirklich darauf aus, den Schlüssel der Eigenschaft an die Vergleichsfunktion übergeben zu können. Aber vielleicht ist das nicht möglich? – Koen

+0

Sie können eine eigene Bibliothek erstellen, wenn Sie eine Vergleichsfunktion wünschen, die ein drittes Argument akzeptiert. Angenommen, Sie möchten das integrierte Vergleichbare verwenden, kann der einzige Unterschied im internen Status der Elemente liegen. –

+0

Du könntest einen enum/Schalter benutzen, um das if/thens etwas aufzuräumen, obwohl es natürlich nicht so elegant ist wie das Übergeben eines Parameters. –

2

Sie kein Protokoll generic machen kann. Es gibt zwei Möglichkeiten, Ihr Problem zu lösen:

Sie könnten eine Wrapper-Struktur erstellen, die nur einen Person-Wert enthält, aber nach einer anderen Kombination von Eigenschaften sortiert.

Alternativ können Sie eine Möglichkeit finden, Methoden zu erstellen, die zwei Dinge vergleichen. Wir haben das in einer Swift Talk-Folge gemacht: https://talk.objc.io/episodes/S01E19-from-runtime-programming-to-functions (wenn du das Video nicht sehen willst, kannst du das Transkript lesen).