2014-12-18 17 views
7

Affronto un problema utilizzando l'enumerazione Non riesco a capire.Errore per la corrispondenza di un'enumerazione utilizzando un'istruzione if

Ecco la dichiarazione di un tipo di enumerazione:

enum SomeType { 
    case un 
    case deux 
    case trois 
} 

allora voglio corrispondere un individuo valori di enumerazione con una dichiarazione if:

var testValue: SomeType = .trois 

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

Tutto va bene!

Ora voglio aggiungere un valore associato solo al primo valore membro:

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

var testValue: SomeType = .trois 

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

Un errore che appare sul if dichiarazione: Could not find member 'trois'

significa enumerazioni può solo essere abbinato utilizzando una dichiarazione switch?

Precisions
Quello che voglio ottenere è: "Fa testvalue è di valore membro del 'trois' senza alcuna considerazione per il valore associato". In altre parole, come abbinare un'enumerazione solo al valore del membro.

Ecco una soluzione attuazione Airspeed Velocity risposte:

// 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") 
} 

risposta

9

enumerazioni che non sono associati tipi sono automaticamente equatable. Enum che hanno tipi associati non lo sono. Questo ha senso, perché solo tu puoi sapere come deve essere gestito il tipo associato (come il numero intero che viene fornito con il tuo valore .un). Anche se .trois non ha un tipo associato, la mancanza di equivocità freebie influisce sull'intero enum. Lo switch funziona in modo leggermente diverso, utilizzando la corrispondenza dei pattern, quindi funziona ancora.

Se volete che il vostro enum con un tipo associato di essere equatable, è possibile definire il proprio operatore di ==:

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, grazie. Nella mia comprensione, ho pensato che il test fosse sul valore del membro e non sul valore membro + valore associato. Tipo di: "Se il valore del membro è lo stesso". Alcuni vecchi riflessi dalla lingua Ada! – Domsware

+0

Dopo aver riflettuto, la tua risposta non è ciò che voglio raggiungere. Devo sapere se una variabile corrisponde a un dato valore membro: nessuna considerazione per il valore associato. In altre parole: "questa variabile ha il suo valore membro uguale a quello". – Domsware

+0

Quindi stai dicendo che vuoi che 'SomeType.un's sia uguale indipendentemente dal fatto che i loro valori associati siano uguali? In tal caso, basta rimuovere la clausola where dall'interruttore quando si definisce '==' (vale a dire fare lo stesso per '.un' come per' .deux' e '.trois'. Ma devi comunque definire' == ' te stesso perché Swift ha bisogno di sentirsi dire che è il comportamento che desideri –