2015-11-12 6 views
31

Ich habe merkwürdiges schnelles Verhalten bemerkt, weil meiner Meinung nach Farbvariable nicht zwangswrapped sein sollte, wenn der Schalter unten geschrieben wird, aber ohne das Entpacken zeigt der Compiler mir eine Fehlermeldung.Warum beim Enum und Switch das Auspacken erforderlich?

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 
} 

wenn Farben Variable zeigt mir, dass Fehler nicht ausgepackten Compiler ist: enter image description here

meiner Meinung nach ist es rasche Inkonsistenz, hat jemand ein paar Ideen?

Antwort

32

Wenn er in einer switch Anweisung verwendet wird, ausgepackt, auch implizit optionals sind nicht automatisch ausgepackt. (Ein Grund könnte sein, dass Sie sie nicht gegen nil sonst passen könnten.)

Also muss man auspacken (entweder gewaltsam mit colours! die stürzen ab, wenn colours == nil oder mit optionaler Bindung) oder - alternativ - Spiel gegen .Red? , die eine Abkürzung für .Some(.Red) ist:

var colours: Colours! 

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

Das gleiche gilt für andere Mustervergleichsausdrücken hält, zB

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

auch dies nichts mit Aufzählungstypen zu tun hat, nur mit implizit ungeöffneten optionals in einem Muster:

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

Ein paar deiner 'Farben' sind' Farben' ;-) – vacawama

+0

@vacawama: Schuld der Autokorrektur :) –

+0

Ja! Autokorrektur korrigierte auch meinen Kommentar. Die Schuld könnte aber wirklich Noah Webster gehören. :-) – vacawama

2

Dies liegt daran, dass Sie colours Variable wie optionalen Typ erstellen. Wenn Sie wie folgt vorgehen:

var colours: Colours 
colours = .Red 

Sie müssen nicht auf diesen Wert unwrappe

Wenn wir schauen, was die optionale Typ ist, werden wir sehen, dass diese Enum ist wie:

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

Und es kann Some Typ wie Int zum Beispiel oder None sein und in diesem Fall hat es keinen Wert.

Wenn Sie machen dies:

var colours: Colours! 

Sie direkt von den ! angezeigt wird, dass dies nicht Colours Typ ist, aber dies ist der enum ImplicitlyUnwrappedOptional<Colours> Typ. Im Moment der Erstellung ist es Some<Colours> wenn es gleich Wert ist aber mit dieser ! haben Sie, dass es enum ImplicitlyUnwrappedOptional<Colours> ist und in einigen nächsten Moment wird es die None sein. Deshalb sollten Sie ! verwenden müssen in switch:

Ihr colours Wert ist ImplicitlyUnwrappedOptional<Colours> Typ und es kann Colours oder nil und Sie haben sein direkt, um anzuzeigen, dass dies Colours Typ in `switch``.

+1

Könnten Sie eine Dokumentation bieten die zeigen, dass eine Variable mit 'erklärt' macht es optional ? – Arc676

+0

@ Arc676 Ich bearbeite Antwort –

+1

'Farben' hat den Typ' ImplicitlyUnwrappedOptional ', nicht' Optional '. –

1

Statt mit:

var colours: Colours! 
colours = .Red 

Verwenden Sie einfach

var colours = Colours.Red 

, die den Trick tun sollten.

+1

Aber ich möchte optionale Farben variabel haben. Es sollte ohne '!' Funktionieren. meiner Meinung nach. – Robert

+2

@roher Das Deklarieren einer Enum-Typ-Variablen als optional ist nicht sehr nützlich, da eine Enumeration einen bestimmten Zustand haben soll. Verwenden Sie einen .None-Status oder einen ähnlichen Status anstelle eines optionalen. – vadian

Verwandte Themen