Использование Swift if let с логическим оператором AND &&
Мы знаем, что мы можем использовать оператор if let
в качестве сокращения, чтобы проверить необязательный nil, а затем распаковать.
Однако я хочу объединить это с другим выражением, используя логический оператор И &&
.
Итак, например, здесь я делаю необязательную цепочку для разворачивания и, возможно, опускаю свой rootViewController на tabBarController. Но вместо того, чтобы иметь вложенные операторы if, я хотел бы объединить их.
if let tabBarController = window!.rootViewController as? UITabBarController {
if tabBarController.viewControllers.count > 0 {
println("do stuff")
}
}
Комбинированное значение:
if let tabBarController = window!.rootViewController as? UITabBarController &&
tabBarController.viewControllers.count > 0 {
println("do stuff")
}
}
Вышеприведенная ошибка компиляции Использование неразрешенного идентификатора 'tabBarController'
Упрощая:
if let tabBarController = window!.rootViewController as? UITabBarController && true {
println("do stuff")
}
Это дает ошибку компиляции Связанное значение в условной привязке должно быть необязательного типа. Проведя различные синтаксические изменения, каждый из них дает другую ошибку компилятора. Мне еще предстоит найти выигрышную комбинацию порядка и круглых скобок.
Итак, вопрос в том, возможно ли и если да, то какой правильный синтаксис?
Обратите внимание, что я хочу сделать это с помощью инструкции if
не a switch
или тройного оператора ?
.
Ответы
Ответ 1
С Swift 1.2 этот теперь возможен. Swift 1.2 и Xcode 6.3 бета-версии выпуска:
Более мощная опция развертывания с, если let - The if let construct теперь можно развернуть сразу несколько опций, а также включить промежуточных булевых условий. Это позволяет выразить условные управляющий поток без ненужного вложения.
С приведенным выше утверждением синтаксис будет следующим:
if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 {
println("do stuff")
}
В этом случае используется предложение where
.
Другой пример: на этот раз отбрасывание AnyObject
в Int
, развертывание необязательного и проверка того, что развернутый необязательный параметр соответствует условию:
if let w = width as? Int where w < 500
{
println("success!")
}
Для тех, кто сейчас использует Swift 3, "where" заменено запятой. Таким образом, эквивалент:
if let w = width as? Int, w < 500
{
println("success!")
}
Ответ 2
В Swift 3 Пример Max MacLeod будет выглядеть следующим образом:
if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
println("do stuff")
}
where
был заменен на ,
Ответ 3
Максимальный ответ правильный и один из способов сделать это. Обратите внимание, что это написано следующим образом:
if let a = someOptional where someBool { }
Сначала выражение someOptional
будет разрешено. Если это не удается, выражение someBool
не будет оцениваться (оценка короткого замыкания, как и следовало ожидать).
Если вы хотите написать это, это может быть сделано так:
if someBool, let a = someOptional { }
В этом случае сначала оценивается someBool
, и только если он вычисляет true, выполняется выражение someOptional
.
Ответ 4
Это невозможно.
Из Swift grammar
ГРАММАТИЧЕСКОЕ ЗАЯВЛЕНИЕ
if-statement → if if-condition code-block else-clauseopt
if-condition → выражение | декларация
else-clause → else код-блок | else if-statement
Значение любого условия в операторе if должно иметь тип, соответствующий протоколу BooleanType. Условие также может быть необязательным объявлением связывания, как описано в разделе "Необязательное связывание"
if-condition должно быть выражением или декларацией. У вас не может быть выражения и декларации.
let foo = bar
- это объявление, оно не оценивает значение, соответствующее BooleanType
. Он объявляет константу/переменную foo
.
Ваше оригинальное решение достаточно хорошее, оно более читаемо, а затем объединяет условия.
Ответ 5
Я думаю, что ваше оригинальное предложение не так уж плохо. Альтернативой (messier) будет:
if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 {
println("do stuff")
}