Ich lerne Swift für iOS 8 / OSX 10.10, indem ich diesem Tutorial folge , und der Begriff " unverpackter Wert " wird mehrmals verwendet, wie in diesem Absatz (unter Objekte und Klasse ):
Wenn Sie mit optionalen Werten arbeiten, können Sie schreiben? vor Operationen wie Methoden, Eigenschaften und Subskription. Ist der Wert vor dem? ist null, alles nach dem? wird ignoriert und der Wert des gesamten Ausdrucks ist null. Andernfalls wird der optionale Wert ausgepackt und alles nach dem? wirkt auf den unverpackten Wert . In beiden Fällen ist der Wert des gesamten Ausdrucks ein optionaler Wert.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
Ich verstehe es nicht und habe ohne Glück im Internet gesucht.
Was bedeutet das?
Bearbeiten
Nach Cezarys Antwort gibt es einen kleinen Unterschied zwischen der Ausgabe des Originalcodes und der endgültigen Lösung (auf dem Spielplatz getestet):
Originalcode
Cezarys Lösung
Die Eigenschaften der Oberklasse werden im zweiten Fall in der Ausgabe angezeigt, während im ersten Fall ein leeres Objekt vorhanden ist.
Soll das Ergebnis nicht in beiden Fällen identisch sein?
Verwandte Fragen und Antworten: Was ist ein optionaler Wert in Swift?
Antworten:
Zunächst müssen Sie verstehen, was ein optionaler Typ ist. Ein optionaler Typ bedeutet grundsätzlich, dass die Variable sein kann
nil
.Beispiel:
Das Fragezeichen zeigt an, dass
canBeNil
dies möglich istnil
.Das würde nicht funktionieren:
Um den Wert aus Ihrer Variablen zu erhalten, falls dieser optional ist, müssen Sie ihn auspacken . Dies bedeutet nur, am Ende ein Ausrufezeichen zu setzen.
Ihr Code sollte folgendermaßen aussehen:
Eine Nebenbemerkung:
Sie können auch Optionen zum automatischen Auspacken deklarieren, indem Sie ein Ausrufezeichen anstelle eines Fragezeichens verwenden.
Beispiel:
Eine alternative Möglichkeit, Ihren Code zu reparieren, ist:
BEARBEITEN:
Der Unterschied, den Sie sehen, ist genau das Symptom dafür, dass der optionale Wert umbrochen wird . Es gibt eine weitere Schicht darüber. Die entpackte Version zeigt nur das gerade Objekt, weil es gut entpackt ist.
Ein schneller Spielplatzvergleich:
Im ersten und zweiten Fall wird das Objekt nicht automatisch entpackt, sodass Sie zwei "Ebenen" (
{{...}}
) sehen, während Sie im dritten Fall nur eine Ebene sehen ({...}
) angezeigt wird, da das Objekt automatisch entpackt wird.Der Unterschied zwischen dem ersten Fall und den beiden zweiten Fällen besteht darin, dass in den zweiten beiden Fällen ein Laufzeitfehler angezeigt wird, wenn "gesetzt"
optionalSquare
istnil
. Mit der Syntax im ersten Fall können Sie Folgendes tun:quelle
init()
Funktion der Klasse initialisiert werden . Ich empfehle, die Kapitel "Die Grundlagen" (behandelt Optionen), "Initialisierung" und "Optionale Verkettung" im von Apple veröffentlichten Swift-Buch zu lesen.Die vorhandene richtige Antwort ist großartig, aber ich fand, dass ich eine gute Analogie brauchte, um dies vollständig zu verstehen, da dies ein sehr abstraktes und seltsames Konzept ist.
Lassen Sie mich diesen "rechtshirnigen" Entwicklern (visuelles Denken) helfen, indem ich zusätzlich zur richtigen Antwort eine andere Perspektive gebe. Hier ist eine gute Analogie, die mir sehr geholfen hat.
Geburtstagsgeschenk-Verpackungsanalogie
Stellen Sie sich Optionals wie Geburtstagsgeschenke vor, die in einer steifen, harten, farbigen Verpackung geliefert werden.
Sie wissen nicht, ob sich etwas in der Verpackung befindet, bis Sie das Geschenk auspacken - vielleicht ist überhaupt nichts darin! Wenn sich etwas darin befindet, könnte es sich um ein weiteres Geschenk handeln, das ebenfalls verpackt ist und möglicherweise auch nichts enthält . Sie könnten sogar 100 verschachtelte Geschenke auspacken, um schließlich festzustellen, dass es nichts anderes als das Verpacken gab .
Wenn der Wert des optionalen nicht ist
nil
, haben Sie jetzt ein Feld mit etwas angezeigt . Insbesondere wenn der Wert nicht explizit eingegeben wird und eine Variable und keine vordefinierte Konstante ist, müssen Sie die Box möglicherweise noch öffnen, bevor Sie etwas Spezifisches darüber wissen können, was sich in der Box befindet, wie welcher Typ es ist oder welcher ist Wert ist.Was ist in der Box?! Analogie
Selbst nachdem Sie die Variable ausgepackt haben, sind Sie immer noch wie Brad Pitt in der letzten Szene in SE7EN ( Warnung : Spoiler und sehr R-bewertete Schimpfwörter und Gewalt), denn selbst nachdem Sie die Gegenwart ausgepackt haben, befinden Sie sich in der folgenden Situation: Sie haben jetzt
nil
oder eine Box mit etwas (aber Sie wissen nicht was).Sie kennen vielleicht die Art des Etwas . Wenn Sie beispielsweise die Variable als Typ deklariert
[Int:Any?]
haben, wissen Sie, dass Sie ein (möglicherweise leeres) Wörterbuch mit ganzzahligen Indizes haben, das umschlossene Inhalte eines alten Typs liefert.Aus diesem Grund kann der Umgang mit Sammlungstypen (Wörterbücher und Arrays) in Swift etwas haarig werden.
Ein typisches Beispiel:
quelle
Swift legt großen Wert auf Typensicherheit. Die gesamte Swift-Sprache wurde unter Berücksichtigung der Sicherheit entwickelt. Es ist eines der Markenzeichen von Swift und eines, das Sie mit offenen Armen begrüßen sollten. Es hilft bei der Entwicklung von sauberem, lesbarem Code und verhindert, dass Ihre Anwendung abstürzt.
Alle Optionen in Swift sind mit dem
?
Symbol gekennzeichnet. Durch die Einstellung des?
in nach dem Namen des Typs , die Sie erklärt werden als optional Sie sind im Wesentlichen Gießen dies nicht als Typ , in dem vor dem?
, sondern als optionalem Typ.Optional verwenden
Dies bedeutet nicht , dass Sie mit einer Art von arbeiten
String
. Dies bedeutet, dass Sie mit einem Typ vonString?
(String Optional oder Optional String) arbeiten. In der Tat, wann immer Sie versuchenZur Laufzeit wird die Debug-Konsole gedruckt
Optional("foobar")
. DerOptional()
Teil " " gibt an, dass diese Variable zur Laufzeit einen Wert haben kann oder nicht, enthält aber gerade die Zeichenfolge "foobar". Diese "Optional()
" -Anzeige bleibt bestehen, es sei denn, Sie führen den so genannten "Auspacken" des optionalen Werts durch.Das Auspacken eines optionalen Elements bedeutet, dass Sie diesen Typ jetzt als nicht optional umwandeln . Dadurch wird ein neuer Typ generiert und der Wert, der sich in diesem optionalen Typ befand, dem neuen nicht optionalen Typ zugewiesen. Auf diese Weise können Sie Operationen für diese Variable ausführen, da vom Compiler ein fester Wert garantiert wurde.
Das bedingte Auspacken prüft, ob der Wert in der Option optional ist
nil
oder nicht. Ist dies nicht dernil
Fall, gibt es eine neu erstellte Konstantenvariable, der der Wert zugewiesen und in die nicht optionale Konstante entpackt wird . Und von dort aus können Sie das nicht optionale imif
Block sicher verwenden .Das bedingte Auspacken von Optionen ist die sauberste Möglichkeit, auf den Wert eines optionalen Elements zuzugreifen. Wenn dieser einen Nullwert enthält, wird alles im if let-Block nicht ausgeführt. Natürlich können Sie wie jede if-Anweisung einen else-Block einfügen
Das gewaltsame Auspacken erfolgt durch Verwendung des sogenannten
!
("Knall") - Operators. Dies ist weniger sicher, ermöglicht jedoch das Kompilieren Ihres Codes. Wenn Sie jedoch den Bang-Operator verwenden, müssen Sie zu 1000% sicher sein, dass Ihre Variable tatsächlich einen festen Wert enthält, bevor Sie sie zwangsweise auspacken.Dies ist ein vollständig gültiger Swift-Code. Es druckt den Wert aus
myString
, der als "foobar" eingestellt wurde. Der Benutzer würdefoobar
in der Konsole gedruckt sehen und das war's auch schon. Nehmen wir jedoch an, der Wert wurde nie festgelegt:Jetzt haben wir eine andere Situation in den Händen. Im Gegensatz zu Objective-C stürzt der Versuch ab, eine Option zwangsweise zu entpacken, und die Option wurde nicht festgelegt
nil
. Wenn Sie versuchen, die Option zu entpacken, um zu sehen, was in Ihrer Anwendung enthalten ist, stürzt sie ab.Auspacken mit Typ Casting . Wie bereits erwähnt, können Sie, obwohl Sie
unwrapping
optional sind, tatsächlich in einen nicht optionalen Typ umwandeln, das nicht optionale jedoch auch in einen anderen Typ umwandeln. Beispielsweise:Irgendwo in unserem Code wird die Variable
something
mit einem Wert gesetzt. Vielleicht verwenden wir Generika oder es gibt eine andere Logik, die dazu führt, dass sich dies ändert. Später in unserem Code möchten wir ihn verwenden, können ihnsomething
aber dennoch anders behandeln, wenn es sich um einen anderen Typ handelt. In diesem Fall möchten Sie dasas
Schlüsselwort verwenden, um dies zu bestimmen:Beachten Sie den Unterschied zwischen den beiden
as
Schlüsselwörtern. Wie zuvor, als wir eine Option gewaltsam ausgepackt haben, haben wir dazu den!
Bang-Operator verwendet. Hier werden Sie das Gleiche tun, aber anstatt nur als nicht optional zu gießen, gießen Sie es auch alsInt
. Und es muss in der Lage sein, niedergeschlagen zu werden, daInt
sonst die Verwendung des Bang-Operators, wenn der Wertnil
Ihre Anwendung ist, abstürzt.Und um diese Variablen überhaupt in irgendeiner Art oder mathematischen Operation zu verwenden, müssen sie dazu ausgepackt werden.
Beispielsweise dürfen in Swift nur gültige Nummerndatentypen derselben Art aufeinander angewendet werden. Wenn Sie einen Typ mit dem
as!
umwandeln, erzwingen Sie den Downcast dieser Variablen, als ob Sie sicher sind , dass es sich um diesen Typ handelt. Daher können Sie sicher arbeiten und Ihre Anwendung nicht zum Absturz bringen. Dies ist in Ordnung, solange die Variable tatsächlich von dem Typ ist, auf den Sie sie übertragen, da Sie sonst ein Durcheinander in Ihren Händen haben.Durch das Casting mit
as!
kann Ihr Code jedoch kompiliert werden. Beim Casting mit einemas?
ist eine andere Geschichte. In der Tatas?
erklärt SieInt
als völlig anderen Datentyp alle zusammen.Jetzt ist es
Optional(0)
Und wenn Sie jemals versucht haben, Ihre Hausaufgaben zu machen, schreiben Sie so etwas wie
Ihr Mathematiklehrer hätte Ihnen wahrscheinlich ein "F" gegeben. Gleiches gilt für Swift. Nur dass Swift lieber gar nicht kompilieren möchte, als Ihnen eine Note zu geben. Denn am Ende des Tages kann die Option tatsächlich Null sein .
Sicherheit geht vor Kinder.
quelle
'?' bedeutet optionaler Verkettungsausdruck,
das '!' bedeutet Kraftwert
quelle