Основы Swift / 4.4. Опционалы и условный код


Видео


Инструкции if и принудительное извлечение
Вы можете использовать if для определения того, что опционал содержит значение, сравнив его с nil. Вы можете выполнить это сравнение с помощью оператора равенства (==) или неравенства (!=).

Если опционал содержит значение, то он однозначно не будет равен nil:
@{4.4\1}
                    
let convertedNumber = Int("132")
if convertedNumber != nil {
    print("convertedNumber содержит некое целое число.")
}
                    
                
Принудительное извлечение
Когда Вы уверены, что опционал содержит значение, Вы можете получить доступ к нему, поставив восклицательный знак (!) после имени опционала. Восклицательный знак фактически говорит: "Я знаю, что этот опционал точно имеет значение; пожалуйста, используй его.". Это известно как принудительное извлечение опционального значения.

Попытка использовать ! для доступа к несуществующему опциональному значению выдают ошибку времени выполнения. Всегда убеждайтесь, что опционал содержит не-nil значение прежде, чем использовать !.
@{4.4\2}
                    
let convertedNumber = Int("132")
if convertedNumber != nil {
    print("convertedNumber содержит целочисленное значение \(convertedNumber!).")
}
                    
                
Опциональное связывание
Вы можете использовать привязку опционалов, чтобы узнать, содержит ли опционал значение, и в случае, если это так, сделать это значение доступным в виде временной величины. Опциональный биндинг может быть использован с if для проверки значения внутри опционала и для извлечения значения в константу или переменную в качестве части единого действия.
@{4.4\3}
                    
let possibleNumber = "132"
if let actualNumber = Int(possibleNumber) {
    print("\"\(possibleNumber)\" имеет целочисленное значение \(actualNumber)")
} else {
    print("\"\(possibleNumber)\" не может быть приведено к целому числу")
}
                    
                
Этот код может быть прочитан как:

"Если опционал типа Int, который был возвращён (Int(possibleNumber)), содержит значение, то нужно задать новую константу с именем actualNumber для значения, содержащегося в опционале."

Если преобразование прошло успешно, то константа actualNumber становится доступной для использования внутри первой ветки if. Она сразу инициализируется значением, содержащимся в опционале: нет необходимости больше использовать суффикс ! для доступа к значению. В этом примере actualNumber просто используется для распечатывания результата преобразования.
Множественные сцепления
Вы можете использовать как константы, так и переменные с опциональным связыванием. Если Вы хотите изменить значение actualNumber внутри первой ветки инструкции if, вы можете написать вместо данного кода код if var actualNumber, а значение, хранимое в опционале, станет доступно в качестве переменной нежели константы.

Вы можете включить столько опциональных биндингов и Булевых условий в одной инструкции if, сколько Вам нужно, разделив их запятыми. Если хотя бы одно из значений опционального биндинга будет nil или любое Булево условие будет выведено в false, то вся инструкция if будет эквивалентна false. Следующие инструкции if эквивалентны:
@{4.4\4}
                    
if let firstNumber = Int("4"), let secondNumer = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
}

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
                    
                
Биндинг и суффиксы/префиксы
Биндинг является транслитерированным словом binding с английского. Другой вариант - связывание, однако биндинг так же нередко употребляется в технической русскоязычной литературе.

Префиксы и суффиксы - это составные части какого-либо выражения, идущие перед и после основного выражения соответственно.
Область видимости констант и переменных
Большая часть констант и переменных, создаваемых Вами ранее, были глобальными константами и переменными: эти величины доступны из любого участка кода. Однако существуют локальные величины по отношению к какому-либо блоку. Ветви инструкции if являются такими блоками кода. Поэтому константы и переменные, созданные в опциональном биндинге в if, доступны только внутри тела этой инструкции:
@{4.4\5}
                    
let possibleNumber = "132"
if let actualNumber = Int(possibleNumber) {
    print("\"\(possibleNumber)\" имеет целочисленное значение \(actualNumber)")
} else {
    print("\"\(possibleNumber)\" не может быть приведено к целому числу")
}
print(actualNumber) // ошибка - actualNumber не зада в данном контексте