2014-12-18 9 views
7

Ich stehe vor einem Problem mit der Enumeration, die ich nicht verstehen kann.Fehler beim Abgleich einer Enumeration mit einer if-Anweisung

Hier Deklaration eines Aufzählungstyp:

enum SomeType { 
    case un 
    case deux 
    case trois 
} 

Dann möchte ich mit einem if Anweisung eine einzelne Aufzählungswerte entsprechen:

var testValue: SomeType = .trois 

if testValue == .trois { 
    // Do something 
} 

Alles ist in Ordnung!

Jetzt mag ich einen zugehörigen Wert hinzufügen nur auf den ersten Mitglied Wert:

enum SomeType { 
    case un(Int) 
    case deux 
    case trois 
} 

var testValue: SomeType = .trois 

if testValue == .trois { 
    // Do something 
} 

ein Fehler als auf der Anweisung if erscheinen: Could not find member 'trois'

Bedeutet dies, Aufzählungen kann nur mit einer switch Aussage abgestimmt werden?

Precisions
Was ich will, ist erreichen: „Does Testvalue das Mitglied Wertes von‚trois‘ist ohne Rücksicht auf zugehörigen Wert“. Mit anderen Worten, wie man eine Enumeration nur auf den Member-Wert anpasst.

Hier ist eine Lösung implementieren Airspeed Velocity Antworten:

// Test equality only on member value 
func == (lhs:SomeType, rhs:SomeType) -> Bool { 
    switch (lhs, rhs) { 
    case (.un(let lhsNum), .un(let rhsNum)):return true 
    case (.deux, .deux): return true 
    case (.trois, .trois): return true 
    default: return false 
    } 
} 

// Test equality on member value AND associated value 
func === (lhs:SomeType, rhs:SomeType) -> Bool { 
    switch (lhs, rhs) { 
    case (.un(let lhsNum), .un(let rhsNum)) where lhsNum == rhsNum: return true 
    case (.deux, .deux): return true 
    case (.trois, .trois): return true 
    default: return false 
    } 
} 

var testValue = SomeType.un(3) 


// Tests 

if testValue == .un(1) { 
    println("Same member value") 
} 


if testValue === .un(3) { 
    println("Same member value AND same associated contents") 
} 

Antwort

9

Aufzählungen, die im Zusammenhang sind keine Typen automatisch gleichzusetzen sind. Enums mit zugeordneten Typen sind nicht verfügbar. Dies ist sinnvoll, da nur Sie wissen können, wie der zugehörige Typ (z. B. die Ganzzahl, die mit Ihrem .un-Wert geliefert wird) behandelt werden soll. Auch wenn keinen assoziierten Typ aufweist, beeinflusst das Fehlen der Gleichmäßigkeit des freien Spiels das gesamte Enum. Switch funktioniert etwas anders, indem er die Mustererkennung verwendet, also funktioniert es immer noch.

Wenn Sie Ihren Enum mit einem zugehörigen Typ wollen gleichzusetzen sein, können Sie Ihren eigenen == Operator definieren:

enum SomeType { 
    case un(Int) 
    case deux 
    case trois 
} 

// possibly there's a more succinct way to do this switch 
func ==(lhs: SomeType, rhs: SomeType) -> Bool { 
    switch (lhs,rhs) { 
    case let (.un(i), .un(j)) where i == j: return true 
    case (.deux,.deux): return true 
    case (.trois, .trois): return true 
    default: return false 
    } 
} 

var testValue: SomeType = .trois 

if testValue == .trois { 
    println("equals .trois") 
} 

// note, for SomeType to work with generic 
// functions that require Equatable, you have 
// to add that too: 
extension SomeType: Equatable { } 

// which means this will work: 
let a: [SomeType] = [.un(1), .deux, .trois] 
find(a, .trois) 
+0

Ok, danke. In meinem Verständnis dachte ich, dass der Test auf Member-Wert und nicht Member-Wert + assoziierter Wert war. Art von: "Wenn der Mitgliedswert derselbe ist". Einige alte Reflexe aus der Ada-Sprache! – Domsware

+0

Nach einigem Nachdenken ist Ihre Antwort nicht das, was ich erreichen möchte. Ich muss wissen, ob eine Variable einem gegebenen Mitgliedswert entspricht: keine Berücksichtigung für den zugehörigen Wert. Mit anderen Worten: "Ist diese Variable gleich ihrem Elementwert?" – Domsware

+0

Sie sagen also, Sie wollen zwei 'SomeType.un' gleich sein, unabhängig davon, ob die zugehörigen Werte gleich sind? In diesem Fall entfernen Sie einfach die where-Klausel aus dem Schalter, wenn Sie '==' definieren (dh machen Sie dasselbe für '.un' wie für' .deux' und '.trois'. Sie müssen aber immer' == 'definieren selbst, weil Swift gesagt werden muss, das ist das Verhalten, das Sie wollen. –

Verwandte Themen