Wir wissen, dass wir eine if let
Anweisung als Abkürzung verwenden können, um nach einer optionalen Null zu suchen und diese dann auszupacken.
Ich möchte dies jedoch mit einem anderen Ausdruck unter Verwendung des logischen AND-Operators kombinieren &&
.
So mache ich hier zum Beispiel eine optionale Verkettung, um meinen rootViewController zu entpacken und optional auf tabBarController herunterzuspielen. Aber anstatt if-Anweisungen verschachtelt zu haben, möchte ich sie kombinieren.
if let tabBarController = window!.rootViewController as? UITabBarController {
if tabBarController.viewControllers.count > 0 {
println("do stuff")
}
}
Kombiniertes Geben:
if let tabBarController = window!.rootViewController as? UITabBarController &&
tabBarController.viewControllers.count > 0 {
println("do stuff")
}
}
Das Obige gibt den Kompilierungsfehler an. Verwendung des nicht aufgelösten Bezeichners 'tabBarController'
Vereinfachung:
if let tabBarController = window!.rootViewController as? UITabBarController && true {
println("do stuff")
}
Dies führt zu einem Kompilierungsfehler. Der gebundene Wert in einer bedingten Bindung muss vom optionalen Typ sein . Nachdem verschiedene syntaktische Variationen versucht wurden, gibt jede einen anderen Compilerfehler aus. Ich habe noch keine erfolgreiche Kombination aus Reihenfolge und Klammern gefunden.
Die Frage ist also, ist es möglich und wenn ja, welche Syntax ist richtig?
Beachten Sie, dass ich dies mit einer if
Anweisung tun möchte, nicht mit einer switch
Anweisung oder einem ternären ?
Operator.
quelle
var foo : Int? = 10; if let bar = foo { if bar == 10 { println("Great success!") }}
if let bar = foo && bar == 10
istUse of unresolved identifier "bar"
(auf der zweitenbar
natürlich).bridgeToObjectiveC
ist in Beta 5 verschwunden (und war möglicherweise nie für den allgemeinen Gebrauch gedacht). 2. Es gibt sowieso einefirst
Methode für Swifts eingebautenArray
Typ.Antworten:
Ab Swift 1.2 ist dies jetzt möglich . In den Beta-Versionshinweisen zu Swift 1.2 und Xcode 6.3 heißt es :
Mit der obigen Aussage wäre die Syntax dann:
Dies verwendet die
where
Klausel.Ein weiteres Beispiel, diesmal Casting
AnyObject
zuInt
, Auspacken der Option und Überprüfen, ob die ausgepackte Option die Bedingung erfüllt:Für diejenigen, die jetzt Swift 3 verwenden, wurde "where" durch ein Komma ersetzt. Das Äquivalent wäre daher:
quelle
In Swift 3 würde das Beispiel von Max MacLeod folgendermaßen aussehen:
Das
where
wurde ersetzt durch,
quelle
if let
kann nur fortgesetzt werden, wenn die Option erfolgreich entpackt wurde und dem neuen Variablennamen zugewiesen ist. Wenn Sie sagten,OR <something else>
dann könnten Sie leicht den ganzen Zweck des umgehenif let
. Führen Sie für ein logisches ODER einfach einen normalen Vorgang durchif
und behandeln Sie innerhalb des Körpers die Tatsache, dass das erste Objekt zu diesem Zeitpunkt noch optional ist (nicht ausgepackt).Max 'Antwort ist richtig und eine Möglichkeit, dies zu tun. Beachten Sie jedoch, dass, wenn so geschrieben:
if let a = someOptional where someBool { }
Der
someOptional
Ausdruck wird zuerst aufgelöst. Wenn dies fehlschlägt, wird dersomeBool
Ausdruck nicht ausgewertet (Kurzschlussauswertung, wie zu erwarten).Wenn Sie dies umgekehrt schreiben möchten, können Sie dies folgendermaßen tun:
if someBool, let a = someOptional { }
In diesem Fall
someBool
wird zuerst ausgewertet, und nur wenn er als wahr ausgewertet wird, wird dersomeOptional
Ausdruck ausgewertet.quelle
Swift 4 werde ich verwenden,
quelle
Es ist nicht möglich.
Aus der schnellen Grammatik
if-Bedingung muss Ausdruck oder Deklaration sein. Sie können nicht sowohl Ausdruck als auch Deklaration haben.
let foo = bar
ist eine Deklaration, die nicht zu einem Wert ausgewertet wird, der dem entsprichtBooleanType
. Es deklariert eine Konstante / Variablefoo
.Ihre ursprüngliche Lösung ist gut genug, sie ist viel besser lesbar als die Kombination der Bedingungen.
quelle
let foo = bar
ist Deklaration nicht Ausdruck. Sie können nicht tunlet boolValue = (let foo = bar)
Ich denke, Ihr ursprünglicher Vorschlag ist nicht schlecht. Eine (chaotischere) Alternative wäre:
quelle
tabBarController
wieder zu besetzen