Wiemy, że możemy użyć if let
instrukcji jako skrótu, aby sprawdzić opcjonalne zero, a następnie rozpakować.
Jednak chcę to połączyć z innym wyrażeniem, używając operatora logicznego AND &&
.
Na przykład tutaj wykonuję opcjonalne tworzenie łańcuchów, aby rozpakować i opcjonalnie obniżyć mój rootViewController do tabBarController. Ale zamiast zagnieżdżać instrukcje if, chciałbym je połączyć.
if let tabBarController = window!.rootViewController as? UITabBarController {
if tabBarController.viewControllers.count > 0 {
println("do stuff")
}
}
Dawanie łączone:
if let tabBarController = window!.rootViewController as? UITabBarController &&
tabBarController.viewControllers.count > 0 {
println("do stuff")
}
}
Powyższe powoduje błąd kompilacji Użycie nierozwiązanego identyfikatora 'tabBarController'
Upraszczanie:
if let tabBarController = window!.rootViewController as? UITabBarController && true {
println("do stuff")
}
Daje to błąd kompilacji Wartość powiązana w powiązaniu warunkowym musi być typu Opcjonalnego . Po próbie różnych wariacji składniowych każda daje inny błąd kompilatora. Nie znalazłem jeszcze zwycięskiej kombinacji kolejności i nawiasów.
Zatem pytanie brzmi, czy jest to możliwe, a jeśli tak, jaka jest poprawna składnia?
Zauważ, że chcę to zrobić z if
instrukcją, a nieswitch
instrukcją lub ?
operatorem trójskładnikowym .
źródło
var foo : Int? = 10; if let bar = foo { if bar == 10 { println("Great success!") }}
if let bar = foo && bar == 10
toUse of unresolved identifier "bar"
(bar
oczywiście po drugiej ).bridgeToObjectiveC
zniknął w wersji beta 5 (i prawdopodobnie nigdy nie był przeznaczony do ogólnego użytku). 2. I tak jestfirst
metoda wbudowanegoArray
typu Swift .Odpowiedzi:
Od wersji Swift 1.2 jest to teraz możliwe . Informacje o wydaniu wersji beta Swift 1.2 i Xcode 6.3 zawierają :
Przy powyższym stwierdzeniu składnia byłaby wtedy następująca:
if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 { println("do stuff") }
Wykorzystuje
where
klauzulę.Inny przykład, tym razem rzutowanie
AnyObject
naInt
, rozpakowanie opcjonalnego i sprawdzenie, czy nieopakowany element opcjonalny spełnia warunek:if let w = width as? Int where w < 500 { println("success!") }
Dla tych, którzy teraz używają Swift 3, „gdzie” zostało zastąpione przecinkiem. Odpowiednik byłby zatem następujący:
if let w = width as? Int, w < 500 { println("success!") }
źródło
W Swift 3 Max MacLeod przykład wyglądałby tak:
if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 { println("do stuff") }
where
Został zastąpiony przez,
źródło
if let
można kontynuować tylko wtedy, gdy opcjonalna pomyślnie rozpakowana i przypisana do nowej nazwy zmiennej. Jeśli tak powiedziałeś,OR <something else>
możesz łatwo ominąć cały celif let
. Dla logicznego OR, po prostu wykonaj normalneif
i wewnątrz ciała zajmij się faktem, że pierwszy obiekt jest nadal opcjonalny w tym momencie (nie jest rozpakowany).Odpowiedź Maxa jest poprawna i można to zrobić. Zauważ jednak, że napisane w ten sposób:
if let a = someOptional where someBool { }
someOptional
Wyrażenie zostanie pierwszy rozwiązany. Jeśli to się nie powiedzie, pliksomeBool
wyrażenie nie zostanie ocenione (ocena zwarcia, jak można się spodziewać).Jeśli chcesz napisać to na odwrót, możesz to zrobić w następujący sposób:
if someBool, let a = someOptional { }
W tym przypadku
someBool
jest oceniany jako pierwszy i tylko wtedy, gdy zwraca wartość true, jestsomeOptional
oceniane wyrażenie.źródło
Swift 4 , użyję,
let i = navigationController?.viewControllers.index(of: self) if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] { // access parent }
źródło
To niemożliwe.
Od gramatyki Swift
warunek-warunek musi być wyrażeniem lub deklaracją. Nie możesz mieć jednocześnie wyrażenia i deklaracji.
let foo = bar
jest deklaracją, nie daje wartości zgodnej zBooleanType
. Deklaruje stałą / zmiennąfoo
.Twoje oryginalne rozwiązanie jest wystarczająco dobre, jest o wiele bardziej czytelne niż połączenie warunków.
źródło
let foo = bar
jest deklaracją, a nie wyrażeniem. nie możesz tego zrobićlet boolValue = (let foo = bar)
Myślę, że twoja pierwotna propozycja nie jest taka zła. (Nieuporządkowaną) alternatywą byłoby:
if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 { println("do stuff") }
źródło
tabBarController
ponownie obsadzić