516 Stimmen

Warum erstellen Sie "Implicitly Unwrapped Optionals", da dies bedeutet, dass Sie wissen, dass es einen Wert gibt?

Warum würden Sie ein "Implicitly Unwrapped Optional" erstellen, anstatt einfach eine normale Variable oder Konstante zu erstellen? Wenn Sie wissen, dass es erfolgreich unwrapped werden kann, warum erstellen Sie dann überhaupt ein Optional? Zum Beispiel, warum ist das:

let someString: String! = "dies ist der String"

nützlicher als:

let someString: String = "dies ist der String"

Wenn "Optionale anzeigen, dass eine Konstante oder Variable 'keinen Wert' haben kann", aber "manchmal aus der Struktur eines Programms klar ist, dass ein Optional immer einen Wert haben wird, nachdem dieser Wert zum ersten Mal festgelegt wurde", warum macht man es dann überhaupt zu einem Optional? Wenn Sie wissen, dass ein Optional immer einen Wert haben wird, macht das es dann nicht eigentlich nicht optional?

15voto

fujianjin6471 Punkte 5028

Apple gibt ein großartiges Beispiel in The Swift Programming Language -> Automatische Referenzzählung -> Beheben von starken Referenzzyklen zwischen Klasseninstanzen -> Unowned-Referenzen und implizit ausgepackte optionale Eigenschaften

class Country {
    let name: String
    var capitalCity: City! // Apple hat diese Zeile endlich bis zur Version 2.0 Vorabversion korrigiert (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 City wird innerhalb des Initialisierers für Country aufgerufen. Der Initialisierer für Country kann jedoch self nicht an den Initialisierer für City übergeben, bis eine neue Country-Instanz vollständig initialisiert ist, wie in Zweiphaseninitialisierung beschrieben.

Um diese Anforderung zu erfüllen, deklarieren Sie die capitalCity-Eigenschaft von Country als eine implizit ausgepackte optionale Eigenschaft.

3voto

Danra Punkte 9156

Die Begründung für implizite Optionals lässt sich leichter erklären, wenn man sich zuerst die Begründung für erzwungenes Entpacken ansieht.

Das erzwungene Entpacken eines Optionals (implizit oder nicht), mit dem !-Operator, bedeutet, dass Sie sicher sind, dass Ihr Code keine Fehler enthält und das Optional bereits einen Wert enthält, wenn es entpackt wird. Ohne den !-Operator würden Sie wahrscheinlich einfach mit einer optionalen Bindung argumentieren:

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

was nicht so schön ist wie

println("\(value!)")

Jetzt ermöglichen implizite Optionals Ihnen, das Vorhandensein eines Optionals auszudrücken, von dem Sie erwarten, dass es immer einen Wert hat, wenn es entpackt wird, in allen möglichen Abläufen. Es geht also nur einen Schritt weiter, um Ihnen zu helfen - indem es die Anforderung lockert, jedes Mal ein ! zu schreiben, um es zu entpacken, und sicherstellt, dass das Programm zur Laufzeit trotzdem einen Fehler meldet, wenn Ihre Annahmen über den Ablauf falsch sind.

3voto

enadun Punkte 2937

Wenn Sie sicher sind, dass ein Wert von einem Optional zurückgegeben wird anstatt von nil, verwenden Sie Implicitly Unwrapped Optionals, um diese Werte direkt aus Optionals abzurufen, während Nicht-Optionals dies nicht können.

// Optional String mit einem Wert
let optionalString: String? = "Dies ist eine optionale Zeichenkette"

// Deklaration einer Implicitly Unwrapped Optional String
let implicitlyUnwrappedOptionalString: String!

// Deklaration einer nicht Optional String
let nonOptionalString: String

// Hier können Sie den Wert eines Optionals abrufen
implicitlyUnwrappedOptionalString = optionalString

// Hier können Sie den Wert eines Optionals nicht abrufen und dies führt zu einem Fehler
nonOptionalString = optionalString

Das ist also der Unterschied zwischen der Verwendung von

let someString : String! und let someString : String

2voto

yoAlex5 Punkte 20661

Implicitly Unwrapped Optional(IUO)

Es handelt sich um eine syntaktische Zuckerart für Optional, die einen Programmierer nicht dazu zwingt, eine Variable zu entpacken. Sie kann für eine Variable verwendet werden, die während des zweiphasigen Initialisierungsprozesses nicht initialisiert werden kann und impliziert nicht nil ist. Diese Variable verhält sich wie nicht nil, ist aber tatsächlich eine optionale Variable. Ein gutes Beispiel sind - Interface Builder's Outlets

Optionale sind normalerweise bevorzugt

var implicitlyUnwrappedOptional: String! //<- Implizit entpackte Optionale
var nonNil: String = ""
var optional: String?

func foo() {
    //einen Wert erhalten
    nonNil.count
    optional?.count

    //Gefährlich - erzwingt das Entpacken, was einen Laufzeitfehler verursachen kann
    implicitlyUnwrappedOptional.count

    //Zu nil zuweisen
//        nonNil = nil //Kompilierfehler - 'nil' kann nicht vom Typ 'String' zugewiesen werden
    optional = nil
    implicitlyUnwrappedOptional = nil
}

0voto

pavel_orekhov Punkte 1174

Ich denke, Optional ist ein schlechter Name für dieses Konstrukt, der viele Anfänger verwirrt.

Andere Sprachen (wie Kotlin und C#) verwenden den Begriff Nullable, was es viel einfacher macht, dies zu verstehen.

Nullable bedeutet, dass Sie einem Variablentyp einen Nullwert zuweisen können. Wenn es also Nullable ist, können Sie Nullen zuweisen, wenn es nur SomeClassType ist, können Sie es nicht. So funktioniert Swift einfach.

Warum benutzen sie das? Nun, manchmal brauchen Sie Nullen, deshalb. Zum Beispiel, wenn Sie wissen, dass Sie ein Feld in einer Klasse haben möchten, aber es nicht einer Instanz dieser Klasse zuweisen können, wenn Sie sie erstellen, sondern später. Ich werde keine Beispiele geben, weil andere sie bereits hier angegeben haben. Ich schreibe das nur, um meinen Senf dazuzugeben.

Übrigens, ich empfehle Ihnen, sich anzuschauen, wie dies in anderen Sprachen funktioniert, wie Kotlin und C#.

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

Andere Sprachen wie Java und Scala haben zwar auch Optionals, aber sie funktionieren anders als Optionals in Swift, weil die Typen in Java und Scala standardmäßig alle nullbar sind.

Alles in allem denke ich, dass dieses Feature in Swift hätte Nullable heißen sollen und nicht Optional...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X