Warum sollten Sie "implizit entpackte Optionen" erstellen, da dies bedeutet, dass Sie wissen, dass es einen Wert gibt?

493

Warum sollten Sie eine "implizit entpackte Option" erstellen, anstatt nur eine reguläre Variable oder Konstante zu erstellen? Wenn Sie wissen, dass es erfolgreich entpackt werden kann, warum sollten Sie dann überhaupt eine Option erstellen? Warum ist das zum Beispiel so:

let someString: String! = "this is the string"

wird nützlicher sein als:

let someString: String = "this is the string"

Wenn "Optionals" angeben, dass eine Konstante oder Variable "keinen Wert" haben darf ", aber" manchmal aus der Struktur eines Programms hervorgeht, dass ein Optional immer einen Wert hat, nachdem dieser Wert zum ersten Mal festgelegt wurde ", worum geht es dann? es überhaupt zu einem optionalen machen? Wenn Sie wissen, dass ein optionales Element immer einen Wert hat, ist es dann nicht optional?

Johnston
quelle

Antworten:

127

Betrachten Sie den Fall eines Objekts, das während der Erstellung und Konfiguration möglicherweise keine Eigenschaften aufweist, danach jedoch unveränderlich und nicht null ist (NSImage wird häufig auf diese Weise behandelt, obwohl es in diesem Fall immer noch nützlich ist, manchmal zu mutieren). Implizit ausgepackte Optionen würden den Code mit relativ geringem Sicherheitsverlust erheblich bereinigen (solange die einzige Garantie besteht, wäre dies sicher).

(Bearbeiten) Um es klar zu sagen: Regelmäßige Optionen sind fast immer vorzuziehen.

Catfish_Man
quelle
459

Bevor ich die Anwendungsfälle für implizit nicht verpackte Optionen beschreiben kann, sollten Sie bereits verstehen, welche Optionen und implizit nicht verpackten Optionen in Swift enthalten sind. Wenn Sie dies nicht tun, empfehle ich Ihnen, zuerst meinen Artikel über Optionen zu lesen

Wann wird eine implizit ausgepackte Option verwendet?

Es gibt zwei Hauptgründe, warum man eine implizit unverpackte Option erstellen würde. Alle haben mit der Definition einer Variablen zu tun, auf die niemals zugegriffen werden kann, nilda der Swift-Compiler Sie sonst immer zwingt, eine Option explizit zu entpacken.

1. Eine Konstante, die während der Initialisierung nicht definiert werden kann

Jede Mitgliedskonstante muss bis zum Abschluss der Initialisierung einen Wert haben. Manchmal kann eine Konstante während der Initialisierung nicht mit ihrem korrekten Wert initialisiert werden, es kann jedoch garantiert werden, dass sie vor dem Zugriff einen Wert hat.

Die Verwendung einer optionalen Variablen umgeht dieses Problem, da eine optionale Variable automatisch mit initialisiert wird nilund der Wert, den sie möglicherweise enthält, weiterhin unveränderlich ist. Es kann jedoch schmerzhaft sein, eine Variable, von der Sie sicher wissen, dass sie nicht gleich Null ist, ständig auszupacken. Implizit unverpackte Optionen bieten die gleichen Vorteile wie eine Option mit dem zusätzlichen Vorteil, dass sie nicht überall explizit ausgepackt werden müssen.

Ein gutes Beispiel hierfür ist, wenn eine Mitgliedsvariable in einer UIView-Unterklasse erst initialisiert werden kann, wenn die Ansicht geladen ist:

class MyView: UIView {
    @IBOutlet var button: UIButton!
    var buttonOriginalWidth: CGFloat!

    override func awakeFromNib() {
        self.buttonOriginalWidth = self.button.frame.size.width
    }
}

Hier können Sie die ursprüngliche Breite der Schaltfläche erst berechnen, wenn die Ansicht geladen wurde. Sie wissen jedoch, dass awakeFromNibdiese vor jeder anderen Methode in der Ansicht (außer der Initialisierung) aufgerufen wird. Anstatt zu erzwingen, dass der Wert in Ihrer gesamten Klasse explizit sinnlos entpackt wird, können Sie ihn als implizit entpackte Option deklarieren.

2. Wenn Ihre App nicht von einem variablen Wesen wiederhergestellt werden kann nil

Dies sollte äußerst selten sein. Wenn Ihre App jedoch nilbeim Zugriff auf eine Variable nicht weiter ausgeführt werden kann, ist es Zeitverschwendung, sie zu testen nil. Wenn Sie eine Bedingung haben, die unbedingt erfüllt sein muss, damit Ihre App weiter ausgeführt werden kann, verwenden Sie normalerweise eine assert. In eine implizit entpackte Option ist eine Zusicherung für Null integriert. Selbst dann ist es oft gut, das Optionale auszupacken und eine aussagekräftigere Aussage zu verwenden, wenn es Null ist.

Wann nicht verwendet werden? Implizit unverpackt Optional

1. Faul berechnete Mitgliedsvariablen

Manchmal haben Sie eine Mitgliedsvariable, die niemals Null sein sollte, die jedoch während der Initialisierung nicht auf den richtigen Wert gesetzt werden kann. Eine Lösung besteht darin, eine implizit nicht verpackte Option zu verwenden. Eine bessere Möglichkeit ist jedoch die Verwendung einer faulen Variablen:

class FileSystemItem {
}

class Directory : FileSystemItem {
    lazy var contents : [FileSystemItem] = {
        var loadedContents = [FileSystemItem]()
        // load contents and append to loadedContents
        return loadedContents
    }()
}

Jetzt wird die Mitgliedsvariable contentserst beim ersten Zugriff initialisiert. Dies gibt der Klasse die Möglichkeit, vor der Berechnung des Anfangswertes in den richtigen Zustand zu gelangen.

Hinweis: Dies scheint # 1 von oben zu widersprechen. Es ist jedoch eine wichtige Unterscheidung zu treffen. Das buttonOriginalWidthObige muss während viewDidLoad festgelegt werden, um zu verhindern, dass jemand die Breite der Schaltflächen ändert, bevor auf die Eigenschaft zugegriffen wird.

2. Überall sonst

Implizit nicht verpackte Optionen sollten größtenteils vermieden werden, da bei falscher Verwendung Ihre gesamte App abstürzt, wenn währenddessen auf sie zugegriffen wird nil. Wenn Sie sich nie sicher sind, ob eine Variable Null sein kann, verwenden Sie immer standardmäßig eine normale Optionale Option. Das Auspacken einer Variablen, die niemals nilsicher ist, tut nicht sehr weh.

Drawag
quelle
4
Diese Antwort sollte für Beta 5 aktualisiert werden. Sie können sie nicht mehr verwenden if someOptional.
Weihnachtsmann
2
@SantaClaus hasValueist direkt auf Optional definiert. Ich bevorzuge die Semantik von hasValuedenen von != nil. Ich denke, es ist viel verständlicher für neue Programmierer, die nicht nilin anderen Sprachen verwendet haben. hasValueist viel logischer als nil.
Drawag
2
Sieht so aus, hasValueals wäre es aus der Beta 6 gezogen worden. Ash hat es aber zurückgesetzt ... github.com/AshFurrow/hasValue
Chris Wagner
1
@newacct In Bezug auf den Rückgabetyp von Objc-Initialisierern handelt es sich eher um eine implizite implizit nicht verpackte Option. Das Verhalten, das Sie für die Verwendung eines "nicht optionalen" Elements beschrieben haben, ist genau das, was ein implizit nicht verpacktes optionales Gerät tun würde (nicht fehlschlagen, bis auf es zugegriffen wird). Ich stimme zu, dass die Verwendung eines nicht optionalen Programms bevorzugt wird, was jedoch nicht immer möglich ist.
Drawag
1
@confile no. Egal was passiert, es wird in Objective-C als Zeiger angezeigt (wenn es optional, implizit entpackt oder nicht optional wäre).
Drawag
56

Implizit entpackte Optionen sind nützlich, um eine Eigenschaft als nicht optional darzustellen, wenn sie wirklich unter der Decke optional sein muss. Dies ist häufig erforderlich, um den Knoten zwischen zwei verwandten Objekten zu binden, die jeweils einen Verweis auf das andere benötigen. Es ist sinnvoll, wenn keine der Referenzen tatsächlich optional ist, aber eine von ihnen Null sein muss, während das Paar initialisiert wird.

Zum Beispiel:

// These classes are buddies that never go anywhere without each other
class B {
    var name : String
    weak var myBuddyA : A!
    init(name : String) {
        self.name = name
    }
}

class A {
    var name : String
    var myBuddyB : B
    init(name : String) {
        self.name = name
        myBuddyB = B(name:"\(name)'s buddy B")
        myBuddyB.myBuddyA = self
    }
}

var a = A(name:"Big A")
println(a.myBuddyB.name)   // prints "Big A's buddy B"

Jede BInstanz sollte immer eine gültige myBuddyAReferenz haben, damit der Benutzer sie nicht als optional behandelt, aber sie muss optional sein, damit wir eine erstellen können, Bbevor wir eine AReferenz haben.

JEDOCH! Diese Art der gegenseitigen Bezugsanforderung ist häufig ein Hinweis auf eine enge Kopplung und ein schlechtes Design. Wenn Sie sich auf implizit entpackte Optionen verlassen, sollten Sie wahrscheinlich ein Refactoring in Betracht ziehen, um die gegenseitigen Abhängigkeiten zu beseitigen.

n8gray
quelle
7
Ich denke, einer der Gründe, warum sie diese @IBOutlet
Sprachfunktion
11
+1 für die Einschränkung "JEDOCH". Es mag nicht immer wahr sein, aber es ist sicherlich etwas, worauf man achten muss.
JMD
4
Sie haben immer noch einen starken Referenzzyklus zwischen A und B. Implizit entpackte Optionen erstellen KEINE schwache Referenz. Sie müssen myByddyA oder myBuddyB immer noch als schwach deklarieren (wahrscheinlich myBuddyA)
drawag
6
Um noch deutlicher zu machen, warum diese Antwort falsch und gefährlich irreführend ist: Implizit unverpackte Optionen haben absolut nichts mit Speicherverwaltung zu tun und verhindern keine Aufbewahrungszyklen. Implizit unverpackte Optionen sind jedoch unter den für die Einrichtung der Zwei-Wege-Referenz beschriebenen Umständen weiterhin nützlich. weak
Fügen Sie
1
@drewag: Du hast recht - ich habe die Antwort bearbeitet, um den Aufbewahrungszyklus zu entfernen. Ich wollte die Rückreferenz schwach machen, aber ich denke, es ist mir durch den Kopf gegangen.
n8gray
37

Implizit ausgepackte Optionen sind ein pragmatischer Kompromiss, um die Arbeit in einer Hybridumgebung, die mit vorhandenen Cocoa-Frameworks und deren Konventionen zusammenarbeiten muss, angenehmer zu gestalten und gleichzeitig eine schrittweise Migration in ein sichereres Programmierparadigma zu ermöglichen - ohne Nullzeiger -, das vom Swift-Compiler erzwungen wird.

Das schnelle Buch im Kapitel " Grundlagen" im Abschnitt " Implizit unverpackte Optionen" lautet:

Implizit entpackte Optionen sind nützlich, wenn bestätigt wird, dass der Wert eines Optionsfelds unmittelbar nach der ersten Definition des Optionsfelds vorhanden ist, und es kann definitiv davon ausgegangen werden, dass es zu jedem späteren Zeitpunkt vorhanden ist. Die implizite Verwendung implizit entpackter Optionen in Swift erfolgt hauptsächlich während der Klasseninitialisierung, wie unter Nicht besessene Referenzen und implizit entpackte optionale Eigenschaften beschrieben .

Sie können sich ein implizit entpacktes optionales Objektiv vorstellen, das die Erlaubnis gibt, dass das optionales Produkt bei jeder Verwendung automatisch entpackt wird. Anstatt bei jeder Verwendung ein Ausrufezeichen nach dem Namen des Optionsfelds zu setzen, setzen Sie ein Ausrufezeichen nach dem Typ des Optionsfelds, wenn Sie es deklarieren.

Dies ist auf Anwendungsfälle zurückzuführen, in denen die Nicht- nilNichtigkeit von Eigenschaften über eine Verwendungskonvention festgelegt wird und vom Compiler während der Klasseninitialisierung nicht erzwungen werden kann. Zum Beispiel die UIViewControllerEigenschaften, die über NIBs oder Storyboards initialisiert werden, wobei die Initialisierung in separate Phasen unterteilt ist. Danach viewDidLoad()können Sie jedoch davon ausgehen, dass Eigenschaften im Allgemeinen vorhanden sind. Andernfalls mussten Sie, um den Compiler zufrieden zu stellen, das erzwungene Entpacken , das optionale Binden oder das optionale Verketten verwenden , um den Hauptzweck des Codes zu verschleiern.

Der obige Teil aus dem Swift-Buch bezieht sich auch auf das Kapitel Automatische Referenzzählung :

Es gibt jedoch ein drittes Szenario, in dem beide Eigenschaften immer einen Wert haben sollten und keine Eigenschaft jemals abgeschlossen sein sollte, nilsobald die Initialisierung abgeschlossen ist. In diesem Szenario ist es nützlich, eine nicht besessene Eigenschaft für eine Klasse mit einer implizit entpackten optionalen Eigenschaft für die andere Klasse zu kombinieren.

Auf diese Weise kann nach Abschluss der Initialisierung direkt auf beide Eigenschaften zugegriffen werden (ohne optionales Entpacken), ohne dass ein Referenzzyklus erforderlich ist.

Dies ist darauf zurückzuführen, dass es sich nicht um eine Sprache handelt, in der Müll gesammelt wird. Daher liegt es an Ihnen als Programmierer, die Aufbewahrungszyklen zu unterbrechen, und implizit ausgepackte Optionen sind ein Werkzeug, um diese Eigenart zu verbergen.

Dies umfasst die Frage "Wann sollten implizit entpackte Optionen in Ihrem Code verwendet werden?" Frage. Als Anwendungsentwickler begegnen Sie ihnen hauptsächlich in Methodensignaturen von in Objective-C geschriebenen Bibliotheken, die keine optionalen Typen ausdrücken können.

Aus der Verwendung von Swift mit Kakao und Objective-C, Abschnitt Arbeiten mit Null :

Da Objective-C keine Garantie dafür gibt, dass ein Objekt nicht Null ist, macht Swift alle Klassen in Argumenttypen und Rückgabetypen in importierten Objective-C-APIs optional. Bevor Sie ein Objective-C-Objekt verwenden, sollten Sie überprüfen, ob es nicht fehlt.

In einigen Fällen können Sie absolut sicher sein, dass eine Objective-C-Methode oder -Eigenschaft niemals eine nilObjektreferenz zurückgibt . Um die Arbeit mit Objekten in diesem speziellen Szenario zu vereinfachen, importiert Swift Objekttypen als implizit entpackte Optionen . Implizit ausgepackte optionale Typen umfassen alle Sicherheitsmerkmale optionaler Typen. Darüber hinaus können Sie direkt auf den Wert zugreifen, ohne nach zu suchenniloder selbst auspacken. Wenn Sie auf den Wert in dieser Art von optionalem Typ zugreifen, ohne ihn zuerst sicher zu entpacken, prüft die implizit entpackte Option, ob der Wert fehlt. Wenn der Wert fehlt, tritt ein Laufzeitfehler auf. Daher sollten Sie eine implizit entpackte Option immer selbst überprüfen und auspacken, es sei denn, Sie sind sicher, dass der Wert nicht fehlen kann.

... und dahinter lag Drachen

Palimondo
quelle
Vielen Dank für diese gründliche Antwort. Können Sie sich eine kurze Checkliste vorstellen, wann implizit nicht verpackte Optionen verwendet werden sollten und wann eine Standardvariable ausreichen würde?
Hairgami_Master
@Hairgami_Master Ich habe meine eigene Antwort mit einer Liste und konkreten Beispielen
hinzugefügt
18

Einzeilige (oder mehrzeilige) einfache Beispiele decken das Verhalten von Optionen nicht sehr gut ab - ja, wenn Sie eine Variable deklarieren und ihr sofort einen Wert geben, macht eine Option keinen Sinn.

Der beste Fall, den ich bisher gesehen habe, ist das Setup, das nach der Objektinitialisierung erfolgt, gefolgt von einer Verwendung, die "garantiert" diesem Setup folgt, z. B. in einem View Controller:

class MyViewController: UIViewController {

    var screenSize: CGSize?

    override func viewDidLoad {
        super.viewDidLoad()
        screenSize = view.frame.size
    }

    @IBAction printSize(sender: UIButton) {
        println("Screen size: \(screenSize!)")
    }
}

Wir wissen printSize, dass der Aufruf nach dem Laden der Ansicht erfolgt - es handelt sich um eine Aktionsmethode, die mit einem Steuerelement in dieser Ansicht verbunden ist, und wir haben darauf geachtet, sie nicht anders aufzurufen. So können wir uns einige optionale Überprüfungen / Bindungen mit dem sparen !. Swift kann diese Garantie nicht erkennen (zumindest bis Apple das Problem mit dem Anhalten gelöst hat), sodass Sie dem Compiler mitteilen, dass sie vorhanden ist.

Dies bricht jedoch die Typensicherheit bis zu einem gewissen Grad. An jedem Ort, an dem Sie eine implizit ausgepackte Option haben, kann Ihre App abstürzen, wenn Ihre "Garantie" nicht immer gilt. Daher sollten Sie diese Funktion sparsam verwenden. Außerdem !klingt es so, als würdest du schreien, wenn du die ganze Zeit benutzt, und das gefällt niemandem.

Rickster
quelle
Warum initialisieren Sie screenSize nicht einfach auf CGSize (Höhe: 0, Breite: 0) und sparen sich die Mühe, die Variable bei jedem Zugriff schreien zu müssen?
Martin Gordon
Eine Größe war möglicherweise nicht das beste Beispiel, da CGSizeZerosie im realen Gebrauch ein guter Sentinel-Wert sein kann. Aber was ist, wenn Sie eine Größe von der Feder geladen haben, die tatsächlich Null sein könnte? CGSizeZeroWenn Sie dann als Sentinel verwenden, können Sie nicht zwischen einem nicht festgelegten und einem auf Null gesetzten Wert unterscheiden. Darüber hinaus gilt dies ebenso gut für andere Typen, die von nib (oder irgendwo anders danach init) geladen wurden : Zeichenfolgen, Verweise auf Unteransichten usw.
Rickster
2
Ein Teil des optionalen Punkts in funktionalen Sprachen besteht darin, keine Sentinel-Werte zu haben. Sie haben entweder einen Wert oder Sie tun es nicht. Sie sollten keinen Fall haben, in dem Sie einen Wert haben, der auf einen fehlenden Wert hinweist.
Wayne Tanner
4
Ich denke, Sie haben die Frage des OP falsch verstanden. Das OP fragt nicht nach dem allgemeinen Fall für Optionals, sondern speziell nach der Notwendigkeit / Verwendung implizit entpackter Optionals (dh nicht let foo? = 42, eher let foo! = 42). Das spricht das nicht an. (Dies kann eine relevante Antwort über Optionals sein, wohlgemerkt, aber nicht über implizit ausgepackte Optionals, die ein anderes / verwandtes Tier sind.)
JMD
15

Apple gibt ein gutes Beispiel in der Programmiersprache Swift -> Automatische Referenzzählung -> Auflösen starker Referenzzyklen zwischen Klasseninstanzen -> Nicht besessene Referenzen und implizit nicht verpackte optionale Eigenschaften

class Country {
    let name: String
    var capitalCity: City! // Apple finally correct this line until 2.0 Prerelease (let -> var)
    init(name: String, capitalName: String) {
        self.name = name
        self.capitalCity = City(name: capitalName, country: self)
    }
}

class City {
    let name: String
    unowned let country: Country
    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

Der Initialisierer für Citywird aus dem Initialisierer für heraus aufgerufen Country. Der Initialisierer für Countrykann jedoch erst selfan den CityInitialisierer übergeben werden, wenn eine neue CountryInstanz vollständig initialisiert ist, wie unter Zweiphaseninitialisierung beschrieben .

Um diese Anforderung zu erfüllen, deklarieren Sie die capitalCityEigenschaft von Countryals implizit entpackte optionale Eigenschaft.

fujianjin6471
quelle
Das in dieser Antwort erwähnte Tutorial ist hier .
Franklin Yu
3

Die Gründe für implizite Optionen lassen sich leichter erklären, indem zunächst die Gründe für das erzwungene Auspacken betrachtet werden.

Erzwungenes Auspacken eines optionalen (impliziten oder nicht impliziten) mit dem! Operator bedeutet, dass Sie sicher sind, dass Ihr Code keine Fehler enthält und das optionale Code bereits einen Wert hat, in dem es entpackt wird. Ohne das ! Operator, würden Sie wahrscheinlich nur mit einer optionalen Bindung behaupten:

 if let value = optionalWhichTotallyHasAValue {
     println("\(value)")
 } else {
     assert(false)
 }

das ist nicht so schön wie

println("\(value!)")

Mit impliziten Optionen können Sie jetzt ausdrücken, dass in allen möglichen Flows ein optionales Element vorhanden ist, von dem Sie erwarten , dass es beim Auspacken immer einen Wert hat. Es geht also noch einen Schritt weiter, um Ihnen zu helfen - indem Sie die Anforderungen an das Schreiben des! jedes Mal auspacken und sicherstellen, dass die Laufzeit weiterhin fehlerhaft ist, falls Ihre Annahmen über den Ablauf falsch sind.

Danra
quelle
1
@newacct: Nicht-Null in allen möglichen Flüssen durch Ihren Code ist nicht dasselbe wie Nicht-Null von der übergeordneten Initialisierung (Klasse / Struktur) durch Freigabe. Interface Builder ist das klassische Beispiel (aber es gibt viele andere verzögerte Initialisierungsmuster): Wenn eine Klasse immer nur von einer Schreibfeder aus verwendet wird, werden keine Ausgangsvariablen festgelegt init(die Sie möglicherweise nicht einmal implementieren), aber sie ' wird garantiert nach awakeFromNib/ eingestellt viewDidLoad.
Rickster
3

Wenn Sie sicher wissen, ein Wert , der Rückkehr von einem optionalen statt nil, Implizit Unwrapped Optionals verwenden , um direkt die Werte von optionals und nicht optionals fangen nicht.

//Optional string with a value
let optionalString: String? = "This is an optional String"

//Declaration of an Implicitly Unwrapped Optional String
let implicitlyUnwrappedOptionalString: String!

//Declaration of a non Optional String
let nonOptionalString: String

//Here you can catch the value of an optional
implicitlyUnwrappedOptionalString = optionalString

//Here you can't catch the value of an optional and this will cause an error
nonOptionalString = optionalString

Das ist also der Unterschied zwischen der Verwendung von

let someString : String! und let someString : String

enadun
quelle
1
Dies beantwortet die Frage des OP nicht. OP weiß, was eine implizit unverpackte Option ist.
Franklin Yu
0

Ich denke, es Optionalist ein schlechter Name für dieses Konstrukt, das viele Anfänger verwirrt.

Andere Sprachen (z. B. Kotlin und C #) verwenden den Begriff Nullable, und dies erleichtert das Verständnis erheblich.

Nullablebedeutet, dass Sie einer Variablen dieses Typs einen Nullwert zuweisen können. Wenn dies der Nullable<SomeClassType>Fall ist , können Sie ihm Nullen zuweisen. Wenn dies nur der Fall ist SomeClassType, können Sie dies nicht. So funktioniert Swift.

Warum sie benutzen? Manchmal muss man Nullen haben, deshalb. Wenn Sie beispielsweise wissen, dass Sie ein Feld in einer Klasse haben möchten, es aber beim Erstellen einer Instanz dieser Klasse nichts zuweisen können, werden Sie dies später tun. Ich werde keine Beispiele nennen, weil die Leute sie hier bereits zur Verfügung gestellt haben. Ich schreibe das nur auf, um meine 2 Cent zu geben.

Übrigens, ich schlage vor, Sie schauen sich an, wie dies in anderen Sprachen wie Kotlin und C # funktioniert.

Hier ist ein Link, der diese Funktion in Kotlin erklärt: https://kotlinlang.org/docs/reference/null-safety.html

Andere Sprachen wie Java und Scala haben zwar Optionals, funktionieren jedoch anders als Optionals in Swift, da die Typen von Java und Scala standardmäßig alle nullwertfähig sind.

Alles in allem denke ich, dass diese Funktion Nullablein Swift benannt worden sein sollte und nicht Optional...

Hallo du
quelle
0

Implicitly Unwrapped Optionalist ein syntaktischer Zucker Optional, der einen Programmierer nicht zwingt, eine Variable zu entpacken. Es kann für eine Variable verwendet werden, die während nicht initialisiert werden kann two-phase initialization processund nicht Null impliziert . Diese Variable verhält sich wie Nicht-Null , ist jedoch eine optionale Variable. Ein gutes Beispiel ist - Interface Builder's Outlets

Optional in der Regel sind vorzuziehen

var nonNil: String = ""
var optional: String?
var implicitlyUnwrappedOptional: String!

func foo() {
    //get a value
    nonNil.count
    optional?.count

    //Danderour - makes a force unwrapping which can throw a runtime error
    implicitlyUnwrappedOptional.count

    //assign to nil
//        nonNil = nil //Compile error - 'nil' cannot be assigned to type 'String'
    optional = nil
    implicitlyUnwrappedOptional = nil
}
yoAlex5
quelle