Warum kann Swift außerhalb von Block Swift keinen Wert sehen, der einer nicht initialisierten Variablen im Block zugewiesen ist?


RichardYY

Wie wird in Swift5 ohne Wert deklariert? Wird die erste Zuweisung zur eigentlichen Deklaration?

Und sollten wir vermeiden, in Swift wertlos zu deklarieren?

var v:String;
if true {
    v = "Hello"
    print(v) // print "Hello" when without the print below
}
print(v) // variable 'v' used before being initialized
var v:String="";
if true {
    v = "Hello"
    print(v) // print "Hello"
}
print(v) // print "Hello"
matt

Nun, die Nachricht ist nicht sehr hilfreich, und das ist das Problem. Dieses Muster (das ich als berechnete Initialisierung bezeichne ) ist vollkommen legal und nützlich und kann - erstaunlicherweise - sogar letanstelle von verwendet werden var. Sie müssen die nicht initialisierte Variable jedoch über alle möglichen Pfade initialisieren, bevor Sie sie verwenden. Also hast du:

var v:String
if true {
    v = "Hello"
}
print(v) // error

Aber halte mein Bier und schau dir das an :

var v:String
if true {
    v = "Hello"
} else {
    v = "Goodbye"
}
print(v) // fine!

Oder auch:

let v:String
if true {
    v = "Hello"
} else {
    v = "Goodbye"
}
print(v) // fine!

Erstaunlich, was?

Nun könnte man sagen: OK, aber es truewird immer wahr sein, also ist es dumm, mich die Regel "Alle Pfade" erfüllen zu lassen. Schade! Der Compiler besteht trotzdem darauf und lässt Sie später mit einer Warnung los, dass das elsenicht ausgeführt wird. Mit einer Warnung können Sie jedoch kompilieren. ein Fehler nicht. Die Wahrheit ist, dass Ihr Beispiel sehr künstlich ist. Dies ist jedoch eine reale Möglichkeit:

let v:String
if self.someBoolProperty {
    v = "Hello"
} else {
    v = "Goodbye"
}
print(v) // fine!

Dies ist nicht nur legal, sondern auch das Muster, das Apple unter bestimmten, etwas schwierigen Umständen empfiehlt . Beispielsweise wird es in Apples eigenem Beispielcode verwendet, der zeigt, wie die Swift 5-Ergebnisstruktur verwendet wird:

let result: Result<Int, EntropyError>
if count < AsyncRandomGenerator.entropyLimit {
    // Produce numbers until reaching the entropy limit.
    result = .success(Int.random(in: 1...100))
} else {
    // Supply a failure reason when the caller hits the limit.
    result = .failure(.entropyDepleted)
}

Verwandte Artikel