Ich möchte zwei optionals in einer if-Anweisung auspacken, aber der Compiler beschwert sich über einen erwarteten Ausdruck hinter dem Operator an der Kennwortkonstante.
if let email = self.emailField?.text && let password = self.passwordField?.text
{
//do smthg
}
In Swift erledigt.
Großartige Neuigkeiten. Das Entpacken mehrerer Optionals in einer einzelnen Zeile wird jetzt in Swift 1.2 (XCode 6.3 Beta, Veröffentlicht 2/9/15) unterstützt.
Kein Tuple/Switch-Pattern-Matching mehr erforderlich. Es ist tatsächlich sehr nahe an der ursprünglich vorgeschlagenen Syntax (Danke fürs Zuhören, Apple!)
if let email = emailField?.text, password = passwordField?.text {
}
Eine weitere schöne Sache ist, dass Sie auch where
für eine "Schutzbedingung" hinzufügen können:
var email: String? = "[email protected]"
var name: String? = "foo"
if let n = name, e = email where contains(e, "@") {
println("name and email exist, email has @")
}
Referenz: Versionshinweise zu XCode 6.3 Beta
Update für Swift 3:
if let email = emailField?.text, let password = passwordField?.text {
}
vor jeder Variablen muss jetzt ein Schlüsselwort let stehen
Wie wäre es, die Optionals in ein Tuple zu packen und switch zum Pattern-Match zu verwenden?
switch (self.emailField?.text, self.passwordField?.text) {
case let (.Some(email), .Some(password)):
// unwrapped 'email' and 'password' strings available here
default:
break
}
Es ist definitiv etwas lauter, aber es könnte auch mit einer where -Klausel kombiniert werden.
Die Verwendung
if let x = y {
}
ist nicht gleichbedeutend mit
if (let x = y) { // this is actually not allowed
}
"if let" ist effektiv ein Zwei-Wort-Schlüsselwort, das äquivalent zu ist
if y != nil {
let x = y!
// rest of if let block
}
Before Swift 1.2
Wie @James habe ich auch eine unwrap
-Funktion erstellt, diese verwendet jedoch den vorhandenen if let
für den Steuerfluss anstelle eines Abschlusses:
func unwrap<T1, T2>(optional1: T1?, optional2: T2?) -> (T1, T2)? {
switch (optional1, optional2) {
case let (.Some(value1), .Some(value2)):
return (value1, value2)
default:
return nil
}
}
Dies kann wie folgt verwendet werden:
if let (email, password) = unwrap(self.emailField?.text, self.passwordField?.text)
{
// do something
}
Von: https://Gist.github.com/tomlokhorst/f9a826bf24d16cb5f6a3
Wenn Sie mehr Fälle behandeln möchten (z. B. wenn eines der beiden Felder ist nil), ist eine switch
-Anweisung besser geeignet.
Schnell 4
if let suggestions = suggestions, let suggestions1 = suggestions1 {
XCTAssert((suggestions.count > suggestions1.count), "TEST CASE FAILED: suggestion is nil. delete sucessful");
}
Ich kann nicht erklären, warum der obige Code nicht funktioniert, aber dies wäre ein guter Ersatz:
if let email = self.emailField?.text
{
if let password = self.passwordField?.text
{
//do smthg
}
}
Basierend auf der Antwort von @ Joel habe ich eine Hilfsmethode erstellt.
func unwrap<T, U>(a:T?, b:U?, handler:((T, U) -> ())?) -> Bool {
switch (a, b) {
case let (.Some(a), .Some(b)):
if handler != nil {
handler!(a, b)
}
return true
default:
return false
}
}
// Verwendungszweck
unwrap(a, b) {
println("\($0), \($1)")
}