2015-11-12 10 views
31

Ho notato un comportamento strano, perché a mio parere la variabile dei colori non dovrebbe essere forzata da scartare in caso di switch scritto di seguito, ma senza compilatore di unwrapping mi mostra un messaggio di errore.Perché è necessario forzare lo scostamento in caso di enumerazione e commutazione?

enum Colours: Int { 
case Red = 0, White, Black 
} 

var colours: Colours! 
colours = .Red 

switch colours! { // <-- why I have to unwrap colours? As you can see colours are declared as '!' 
case .Red: break 
default: break 
} 

se la variabile colori non è da scartare compilatore mi dimostra che l'errore: enter image description here

a mio parere che è chiamata rapida incoerenza, qualcuno ha qualche idea?

risposta

32

Quando utilizzato in una dichiarazione switch, anche implicitamente da scartare optional non sono automaticamente scartato. (Una ragione potrebbe essere che si non si poteva abbinarli contro nil altrimenti.)

modo da avere a scartarlo (sia forzatamente con colours! che sarà in crash se colours == nil, o con optional vincolante), o - in alternativa - partita contro .Red? che è una scorciatoia per .Some(.Red):

var colours: Colours! 

switch colours { 
case .Red?: 
    break // colours is .Red 
default: 
    break // colours is .White, .Black or nil 
} 

Lo stesso vale per altre espressioni pattern-matching, es

if case .Red? = colours { 
    // colours is .Red 
} else { 
    // colours is .White, .Black or nil 
} 

Anche questo non ha nulla a che fare con tipi di enumerazione, solo con implicitamente optionals da scartare in un modello:!

let x : Int! = 1 

switch x { 
case nil: 
    break // x is nil 
case 1?: 
    break // x is 1 
default: 
    break // x is some other number 
} 
+0

Alcuni dei tuoi 'colori 'sono' colori' ;-) – vacawama

+0

@vacawama: incolpare la correzione automatica :) –

+0

Sì! La correzione automatica correggeva anche il mio commento. La colpa potrebbe comunque appartenere a Noah Webster. :-) – vacawama

2

Questo perché si crea una variabile colours come tipo facoltativo. Se fate così:

var colours: Colours 
colours = .Red 

voi non dovrete unwrappe questo valore

Se guardiamo a ciò che il tipo opzionale, vedremo che questo è enum come:

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

E può essere Some Tipo come Int per esempio o None e in questo caso ha valore nullo.

quando si effettua questo:

var colours: Colours! 

direttamente è indicato dalle ! che questo non è Colours tipo, ma questo è il tipo enum ImplicitlyUnwrappedOptional<Colours>. Al momento della creazione sarà Some<Colours> se uguale valore ma con questo ! si ha che è enum ImplicitlyUnwrappedOptional<Colours> e in qualche momento successivo sarà lo None. Ecco perché è necessario utilizzare ! in switch:

Il vostro valore colours è ImplicitlyUnwrappedOptional<Colours> tipo e può essere Colours o nil e si deve indicare direttamente che si tratta Colours tipo in `switch``.

+1

Potrebbe fornire qualche documentazione che attesti che dichiarando una variabile con '' rende facoltativa ? – Arc676

+0

@ Arc676 modifica la risposta –

+1

'colors' ha il tipo' ImplicitlyUnwrappedOptional ', non' Opzionale '. –

1

Invece di usare:

var colours: Colours! 
colours = .Red 

Basta usare

var colours = Colours.Red 

Questo dovrebbe fare il trucco.

+1

Ma voglio avere colori opzionali variabili. Dovrebbe funzionare senza "!" secondo me. – Robert

+2

@roher Dichiarare una variabile di tipo enum come facoltativo non è molto utile poiché un enum è progettato per avere uno stato definito. Usa uno stato .'None' o simile piuttosto che un opzionale. – vadian

Problemi correlati