Schnelle variable Dekorationen mit "?" (Fragezeichen) und "!" (Ausrufezeichen)

106

Ich verstehe, dass in Swift alle Variablen mit einem Wert gesetzt werden müssen und dass wir mithilfe von Optionen eine Variable setzen können, auf die nilanfänglich gesetzt werden soll.

Was ich nicht verstehe ist, was das Setzen einer Variablen mit a !bewirkt, weil ich den Eindruck hatte, dass dies einen Wert von einem optionalen "entpackt". Ich dachte, auf diese Weise garantieren Sie, dass in dieser Variablen ein Wert zum Entpacken vorhanden ist, weshalb Sie ihn bei IBActions und solchen verwenden.

Einfach ausgedrückt, auf welche Variable wird initialisiert, wenn Sie so etwas tun:

var aShape : CAShapeLayer!

Und warum / wann sollte ich das tun?

Jason Renaldo
quelle
Sie würden dies tun, um festzustellen, dass eine Variable nicht null ist, nachdem Sie diese Tatsache überprüft haben.
Matthias
Ich denke nicht, dass dies als Duplikat markiert werden sollte. "Was ist optional?" ist nicht die gleiche Frage wie "Was ist der Unterschied zwischen den beiden Arten von Optionen?" Das ist so ziemlich das, was diese Frage ist
Jiaaro
@Jiaaro Selbst in diesem Fall gibt es bereits unzählige Fragen zu Optionen, implizit ausgepackten Optionen und dergleichen. Sie können sich auch auf diesen beziehen: stackoverflow.com/questions/24272781/…
Jack
@ JackWu Ok, aber ich bin mir ziemlich sicher, dass diese Frage kein Duplikat war, als sie gestellt wurde. (Es wurde zum Beispiel eine ganze Woche vor Ihrem Beispiel gefragt)
Jiaaro
@ Jiaaro Sie machen einen guten Punkt, ich habe nicht bemerkt, dass dies älter war. Vielleicht sollte der andere stattdessen als Duplikat von diesem markiert werden.
Jack

Antworten:

145

In einer Typdeklaration !ähnelt das dem ?. Beide sind optional, aber das !ist " implizit entpackt" optional , was bedeutet, dass Sie es nicht entpacken müssen, um auf den Wert zuzugreifen (aber es kann immer noch null sein).

Dies ist im Grunde das Verhalten, das wir bereits in Ziel-c hatten. Ein Wert kann Null sein, und Sie müssen danach suchen, aber Sie können auch direkt auf den Wert zugreifen, als wäre er nicht optional (mit dem wichtigen Unterschied, dass Sie einen Wert erhalten, wenn Sie nicht nach Null suchen Laufzeit Fehler)

// Cannot be nil
var x: Int = 1

// The type here is not "Int", it's "Optional Int"
var y: Int? = 2

// The type here is "Implicitly Unwrapped Optional Int"
var z: Int! = 3

Verwendung:

// you can add x and z
x + z == 4

// ...but not x and y, because y needs to be unwrapped
x + y // error

// to add x and y you need to do:
x + y!

// but you *should* do this:
if let y_val = y {
    x + y_val
}
Jiaaro
quelle
7
Implizit entpackte Optionen werden in einem treffend benannten Abschnitt ab Seite 56 der Swift-Programmiersprache beschrieben .
Caleb
@Caleb Ich habe einen Link zu dem relevanten Abschnitt der Online-Dokumente hinzugefügt, in dem ich implizit ausgepackte
Optionen
Tolle Informationen, danke. Wenn wir die Sicherheit, die Swift uns bisher aufzwingt, generell lieben, sollten wir viel weniger Fehler produzieren :).
Jason Renaldo
@ Jiaaro: Vielen Dank für das Teilen. Es macht den Benutzer durch das obige Beispiel perfekt zu verstehen. !! :)
Esha
3
Ich denke, der Satz " Dies ist im Grunde das Verhalten, das wir bereits in Ziel-c hatten " kann verwirrend sein. In Objective-C kann man auf einen nilWert zugreifen und tatsächlich damit "arbeiten". Wenn man schnell auf ein implizit entpacktes optionales Element zugreift, während es gleich Null ist, wird eine Laufzeitausnahme ausgelöst.
Sascha Wolf