2016-12-27 4 views
3

Um Aufzählungen zu vergleichen, die eine Int als Ausgangswert hat habe ich hinzugefügt:Vergleichbare Enum mit Int

func <<T: RawRepresentable>(a: T, b: T) -> Bool where T.RawValue: Comparable { 
    return a.rawValue < b.rawValue 
} 

Jetzt kann ich tun:

enum Foo: Int { 
    case a = 1 
    case b = 2 
} 

let a = Foo.a 
let b = Foo.b 

print(a < b) // true 

Aber wie soll ich es machen, damit ich können vergleichen Aufzählungen wie:

print(b < 1) // error 
+1

Müssten Sie nicht ein anderes '<' überschreiben, wo die Operanden ein RawRepresentable und ein Int sind? – matt

+0

Ich habe versucht, aber es versäumt, dies zu tun. Danke für deine Antwort! –

Antwort

2

Sie würden einfach mehr tun, was Sie bereits tun:

func <<T:RawRepresentable>(a:T, b:Int) -> Bool where T.RawValue == Int { 
    return a.rawValue < b 
} 
1

Int ist nicht RawRepresentable, so kann es nicht mit Ihrem < Operator verwendet werden.

Hier sind zwei Korrekturen:

  1. 2 Machen Sie neue < Überlastungen:

    • <<T: RawRepresentable>(a: T, b: Int)
    • <<T: RawRepresentable>(a: Int, b: T)
  2. Int zu RawRepresentable entsprechen Stellen, und überschreiben Sie Ihre vorhandene < Überladung, um zwei generische Typen zu verwenden, die verglichen werden können, wenn sie die gleiche RawValue haben, die selbst Comparable ist.

    extension Int: RawRepresentable { 
        public init?(rawValue: Int) { self.init(rawValue) } 
        public var rawValue: Int { return self } 
    } 
    
    func < <T: RawRepresentable, U: RawRepresentable>(a: T, b: U) -> Bool 
        where T.RawValue: Comparable, T.RawValue == U.RawValue { 
         return a.rawValue < b.rawValue 
    } 
    
    enum Foo: Int { 
        case a = 1 
        case b = 2 
    } 
    
    print(Foo.a < Foo.b) 
    print(Foo.b < 1) 
    
+0

Ich habe das versucht, aber ich habe Schritt 2 vermisst. Danke! –

+0

@Hamish Ooo guter Punkt. Deshalb sollte ich vor dem Posten kompilieren. Lass mich damit rumspielen :) – Alexander

+0

@Hammish Sieh dir meine handliche Arbeit an :) – Alexander

2

Eine etwas generische Version von @matt's solution - die Ihnen einen gegebenen RawRepresentable mit seinem RawValue zu vergleichen erlauben würde. Beachten Sie, dass Sie beide Überladungen für beide < & > implementieren müssen, um alle 4 möglichen Kombinationen von Vergleichen zu ermöglichen.

func < <T : RawRepresentable>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue : Comparable { 
    return lhs.rawValue < rhs 
} // allows b < 1 

func < <T : RawRepresentable>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue : Comparable { 
    return lhs < rhs.rawValue 
} // allows 1 < b 

func > <T : RawRepresentable>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue : Comparable { 
    return lhs.rawValue > rhs 
} // allows b > 1 

func > <T : RawRepresentable>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue : Comparable { 
    return lhs > rhs.rawValue 
} // allows 1 > b 

Obwohl dass gesagt wird, würde ich die Verwendung solcher Überlastungen vorsichtig sein. Es ist nicht so schlimm, Dinge wie b < 1 sagen zu können, aber das Wasser wird trüber, wenn man sagen kann: b < c wo c ein Int ist - es beginnt etwas unklar zu werden, was man tatsächlich vergleicht (ganz zu schweigen von der zusätzlichen Komplexität) um die Auflösung zu überlasten).

Einfach gesagt print(b.rawValue < 1) ist sowohl klar als auch prägnant und ist die Art, wie ich es schreiben würde.