2014-11-11 15 views
30

Ho problemi con l'utilizzo delle stringhe nelle istruzioni switch in Swift.Stringhe nelle istruzioni switch: 'String' non è conforme al protocollo 'IntervalType'

ho un dizionario chiamato opts che viene dichiarato come <String, AnyObject>

ho questo codice:

switch opts["type"] { 
case "abc": 
    println("Type is abc") 
case "def": 
    println("Type is def") 
default: 
    println("Type is something else") 
} 

e sulle linee case "abc" e case "def" ottengo il seguente errore:

Type 'String' does not conform to protocol 'IntervalType' 

Qualcuno può spiegarmi cosa sto facendo male?

risposta

51

Questo errore viene visualizzato quando un optional viene utilizzato in un'istruzione switch. Semplicemente scartare la variabile e tutto dovrebbe funzionare.

switch opts["type"]! { 
    case "abc": 
    println("Type is abc") 
    case "def": 
    println("Type is def") 
    default: 
    println("Type is something else") 
} 

Edit: Nel caso in cui non si vuole fare un scartare forzata del opzionale, è possibile utilizzare guard. Riferimento: Control Flow: Early Exit

+3

Ecco l'unica risposta corretta. –

+0

@JohnFactorial ora contrassegnato come corretto! – Jimmery

+2

Aggiunta la risposta con la soluzione alternativa e _safer_ di seguito. – mikejd

17

Provare a utilizzare:

let str:String = opts["type"] as String 
switch str { 
case "abc": 
    println("Type is abc") 
case "def": 
    println("Type is def") 
default: 
    println("Type is something else") 
} 
+0

appena provato entrambi, e entrambi mi danno ancora l'errore 'Type 'String' non è conforme al protocollo 'IntervalType'' – Jimmery

+0

Che tipo di dizionario è' opts'? – Kirsteins

+0

Ho provato entrambe le versioni e con questo 'var opts = [" tipo ":" Tipo è abc "]' funziona in un parco giochi – Antonio

13

Ho avuto questo stesso messaggio di errore all'interno di prepareForSegue(), che immagino sia abbastanza comune. Il messaggio di errore è piuttosto opaco, ma le risposte qui mi hanno portato sulla giusta strada. Se qualcuno incontra questo, non hai bisogno di alcuna fusione di caratteri, solo un unwrap condizionale intorno l'istruzione switch: -

if let segueID = segue.identifier { 
    switch segueID { 
     case "MySegueIdentifier": 
      // prepare for this segue 
     default: 
      break 
    } 
} 
+0

Un'istruzione 'guard' funziona bene anche all'interno di' prepareForSegue() ':' guard lascia segueID = segue.identifier else {return} ' –

30

Secondo Swift Language Reference:

The type Optional is an enumeration with two cases, None and Some(T), which are used to represent values that may or may not be present.

Così sotto il cofano un tipo di optional assomiglia questo:

enum Optional<T> { 
    case None 
    case Some(T) 
} 

questo significa che si può andare senza Scartare forzata:

switch opts["type"] { 
case .Some("A"): 
    println("Type is A") 
case .Some("B"): 
    println("Type is B") 
case .None: 
    println("Type not found") 
default: 
    println("Type is something else") 
} 

questo può essere più sicuro, perché l'applicazione non vada in crash se type non sono stati trovati in opts dizionario.

+0

questa è probabilmente la risposta migliore, ma non faccio più lo sviluppo di app, quindi non ho modo di testare questo. – Jimmery

+0

la migliore risposta davvero! – Lcsky

+1

Sei stato colpito dal simpatico folletto ribattezzante Swift 3:. Alcuni sono stati rinominati in .some (che per fortuna il formatore del compilatore Swift 3 è stato felice di dirti :-). Ancora la risposta migliore, grazie (ancora di più se torni per una versione Swift 3). – Patru

5

Al posto della forza unwrap pericoloso .. mi trovano più facile per testare il caso facoltativa:

switch opts["type"] { 
    case "abc"?: 
    println("Type is abc") 
    case "def"?: 
    println("Type is def") 
    default: 
    println("Type is something else") 
} 

(See aggiunto al caso?)

Problemi correlati