Использованием быстрым, если с логическим оператором &&


мы знаем, что мы можем использовать if let заявление в виде стенографии, чтобы проверить наличие необязательного нуля, а затем развернуть.

однако я хочу объединить это с другим выражением, используя логический оператор and &&.

так, например, здесь я делаю необязательную цепочку, чтобы развернуть и, возможно, опустить мой 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 оператор или троичный ? оператора.

6 74

6 ответов:

по состоянию на Swift 1.2, это теперь можно. Элемент Swift 1.2 и Xcode 6.3 beta release notes состояние:

более мощный опционный разворачивать с если да - то если позволить построить теперь можно развернуть несколько вариантов сразу, а также включить промежуточные булевы условия. Это позволяет выражать условные управление потоком без лишней вложенности.

С заявлением выше, синтаксис такой:

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, "где" было заменено запятой. Таким образом, эквивалент будет:

if let w = width as? Int, w < 500
{
    println("success!")
}

на Swift 3 пример Макса Маклауда будет выглядеть так:

if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
    println("do stuff")
}

The where был заменен ,

ответ Макса правильный и один из способов сделать это. Обратите внимание, что когда написано таким образом:

if let a = someOptional where someBool { }

The someOptional выражение будет разрешено первым. Если это не удается, то someBool выражение не будет оцениваться (оценка короткого замыкания, как и следовало ожидать).

если вы хотите написать это наоборот, это можно сделать так:

if someBool, let a = someOptional { }

в этом случае someBool сначала вычисляется, и только если это значение true-это someOptional выражение.

это невозможно.

С Swift grammar

ГРАММАТИКА ОПЕРАТОРА IF

if-statement → если if-condition code-block else-clauseopt

если-условие → выражение | декларация

else-clause → другое code-block/другое if-statement

значение любого условия в операторе if должно иметь тип это соответствует протоколу BooleanType. Условие также может быть необязательным объявлением привязки, как описано в разделе необязательная привязка

если-условие должно быть выражение или декларации. Вы не можете иметь как выражение, так и объявление.

let foo = bar - это объявление, оно не оценивает значение, которое соответствует BooleanType. Он объявляет константу / переменную foo.

ваше первоначальное решение достаточно хорошо, оно очень больше читается затем объединение условий.

Swift 4, Я,

let i = navigationController?.viewControllers.index(of: self)
if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] {
    // access parent
}

Я думаю, что ваше первоначальное предположение не так уж плохо. A (messier) альтернативой было бы:

if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 {
    println("do stuff")
}