2014-06-09 4 views
9

Das implizite Abwickeln eines Bool Typ scheint nicht zu funktionieren:Die implizite Abwickeln eines optionalen boolean

var aBoolean: Bool! // nil 
aBoolean = false  // false 
aBoolean    // false 

aBoolean == true  // false 
aBoolean == false  // true 

if aBoolean { 
    "Hum..."   // "Hum..." 
} else { 
    "Normal" 
} 

if aBoolean! { 
    "Hum..." 
} else { 
    "Normal"   // "Normal" 
} 

Wenn ich aBoolean wie var aBoolean: Bool? erklärt hatte, würde dies das erwartete Verhalten gewesen, aber hier, ich don versteh es nicht.

Ist dies das richtige Verhalten? Ich habe keine Unterlagen darüber gefunden.

Danke!

+1

Ich bin gespannt auf "if! Bool! ... eines Tages! – GoZoner

+1

^Daran habe ich auch gedacht! Hah – Dash

+0

Dieser Code wird nicht kompilieren. Sie vermissen eine geschweifte Klammer. – matt

Antwort

8

Der erste Test wird überprüft, ob aBoolean speichert einen Wert eher als Null, was sie tut:

if aBoolean { 
    "Hum..."   // "Hum..." 
else { 
    "Normal" 
} 

Der zweite Test gegen den tatsächlichen boolean Wert Überprüfung in aBoolean gespeichert, was falsch ist:

if aBoolean! { 
    "Hum..." 
} else { 
    "Normal"   // "Normal" 
} 

Dies wird im Swift-Buch im Abschnitt "Implicitly Wrapped Optionals" dargestellt. Ich denke, die implizite Entpackung trifft einfach nicht auf if-Anweisungen zu. Ich stimme es ist seltsam, aber hier ist das Apple-Beispiel:

Sie können immer noch eine implizit ungeöffneten optional wie ein normaler optional behandeln, zu überprüfen, ob es einen Wert enthält:

let assumedString: String! = "An implicitly unwrapped optional string." 

if assumedString { 
    println(assumedString) 
} 
// prints "An implicitly unwrapped optional string." 

Auszug aus: Apple Inc. "Die schnelle Programmiersprache." IBooks. https://itun.es/us/jEUH0.l

+1

Ja, aber die Frage ist, warum er den boolean auspacken muss, wenn der boolean als "implizit unwrapped" deklariert wird, indem das Ausrufezeichen verwendet –

+0

@Dash Bitte beachten Sie den obigen Kommentar – Damien

+0

Got it .. aktualisiert! – Dash

0

Wenn die Deklaration einer Variablen als „implizit ausgepackt“, die !, ist es immer noch ein Optional

Dieser Variablentyp wie die Standard-Variablentyp in Objective-C sehr verhält. Es kann nil zugewiesen werden, aber wenn Sie auf Mitglieder zugreifen, müssen Sie es nicht explizit auspacken. Auf diese Weise ist es genauso "unsicher" wie in ObjC, weil Sie auf Eigenschaften von null

zugreifen können. So wird es am häufigsten verwendet, wenn von Objective-C überbrückt wird. Es ist jedoch immer noch optional, mit dem einzigen Unterschied, dass Sie es nicht auspacken müssen, um auf die Inhalte zuzugreifen.

Ich glaube, das wurde hauptsächlich hinzugefügt, um die Interop zwischen Swift und Obj-C zu unterstützen und es könnte eine gute Übung sein, es sparsam im reinen Swift-Code zu verwenden. (Swift Richtlinien sind ein unscharfes Ding gerade jetzt und jemand könnte mich bald falsch erweisen!)

+0

In pure swift sind sie nützlich für IBOutlets. Diese sind null bis die Spitze geladen wurde, aber von da an haben sie einen Wert. Den Wert jedes Mal zu überprüfen wäre mühsam. Aber hier sind sie für Cocoa-Objekte verwendet, so Verwirrung für Bool! ist kein Problem. –

+0

@SteveWaddicor Großer Punkt! Ich glaube, 'IBOutlets' sind standardmäßig implizit unverpackte Optionals, so dass Sie die '!' - Syntax nirgends benötigen. – Jack

2

Sie machen zwei verschiedene Wahrheitsprüfungen.

Gegeben:

var aBoolean: Bool! // nil 
aBoolean = false  // false 

if aBoolean { 
    "Hum..."   // "Hum..." 
else { 
    "Normal" 
} 

if aBoolean! { 
    "Hum..." 
} else { 
    "Normal"   // "Normal" 
} 

... in der ersten if aBoolean, wird der Wert nicht ausgepackt zu sein, es ist einfach das optionale Typ wird geprüft, ob es speichert einen Wert zu bestimmen.

In der zweiten if aBoolean!, testen Sie den Wahrheitswert der unverpackten Bool.

Um zu sehen, dass es ist tatsächlich implizit ausgepackt zu sein (wenn sie nicht in einem bedingten verwendet), versuchen:

println("value of implicitly-unwrapped aBoolean: \(aBoolean)")

... das wird ‚true‘ drucken, wenn aBoolean eingestellt wird true, 'false', wenn es auf false gesetzt ist, und 'nil', wenn es noch nicht zugewiesen wurde.

1

Hier ist das Verhalten deutlich gezeigt:

> var bool1 : Bool! 
bool1: Bool! = nil 
> bool1 = false 
> (bool1 ? "yes" : "no") 
$R19: (String) = "yes" 

Im oben, da bool1 ist ein optional (die eine Some Instanz wird), die bedingte einfach auswertet bool1 zu true (es ist nicht nil).

> var bool2 : Bool = false 
bool2: Bool = false 
> (bool2 ? "yes" : "no") 
$R25: (String) = "no" 

Wenn bool2 keine optional ist, die bedingte einfach bool2 ausgewertet false (der Wert von bool2)

6

keine Antwort, aber wenn dies ist in der Tat das gewünschte Verhalten mit implizit ungeöffneten booleans Es ist eher störend. Sobald Sie den Ausdruck in jeder Logik Satz verwenden wird es ausgepackt bekommen:

var aBoolean: Bool! = false 

if !aBoolean { 
    "I'm unwrapping"   // "I'm unwrapping" 
} 

if aBoolean == false { 
    "I'm unwrapping"   // "I'm unwrapping" 
} 

Sagen Sie dies an einem gewissen Punkt in Ihrem Code ein, Ihre Modelländerungen und der Zustand umgekehrt wird, löschen Sie das nicht.

if aBoolean { 
    "I'm unwrapping"   // <- ouch 
} 

Sie haben gerade geschraubt. Bringt mich dazu, das implizite Auspacken zu vermeiden.

+0

Normalerweise sollten Sie das implizite Auspacken vermeiden. Es ist Motivation Fälle wie "IBOutlets".Hier haben Sie eine Klasse mit Membervariablen, die nach dem Ende von init() immer noch nil sind, aber beim Laden der nib einen Wert erhalten. Von "wayFromNib()" an haben sie also nie einen Nullwert und das Auspacken wäre sinnlos. Diese Dinge sind Cocoa-Objekte, die nicht boolen, sodass das von Ihnen aufgeworfene Problem nicht zutrifft. Es gibt möglicherweise andere ähnliche Fälle für die Verwendung impliziter Unwrapping. Aber für den allgemeinen Gebrauch sollten Sie gewöhnliche Bedingungen verwenden. –

+0

Ich argumentiere nicht, dass die richtigen Anwendungen der impliziten Entfaltung selten sind. Alles, was ich sage, ist, dass eine bessere Implementierung wäre, sich wie ein Boolescher Code zu verhalten, es sei denn, Sie versuchen explizit, ihn mit "if let" auszupacken ... –

+0

Die richtigen Anwendungen des impliziten Entpackens für einen Bool sind nicht existent. Ihr Vorschlag würde den Gebrauch von, wenn mit irgendeinem anderen implizit unverpackten Typ, für keinen Vorteil brechen. –

Verwandte Themen