if let
Сравнение с nil говорит, пуста ли коробка, но не открывает её. Чтобы воспользоваться подарком, коробку открывают. Если внутри что-то есть, подарок достают и работают с ним, а если пусто — делают что-то другое. В Swift if let открывает опционал так:
let typed = "25"
if let age = Int(typed) {
print("next year:", age + 1) // next year: 26
} else {
print("not a number")
}Давайте разберём программу по строкам:
Int(typed)превращает текст вInt?, и в этой коробке лежит25.if let age = …открывает коробку. Внутри есть число, поэтому Swift заводит константуageтипаIntсо значением25и выполняет блок в фигурных скобках.age— обычное целое число, иage + 1складывается без ошибки: программа печатаетnext year: 26.- Ветку
elseпрограмма пропускает.
Если заменить "25" на "abc", коробка окажется пустой. Константа age тогда не появится, первый блок не выполнится, а else напечатает not a number.
Как устроена запись
Такую проверку называют привязкой опционала: значение из коробки привязывают к новому имени. Запись if let age = Int(typed) состоит из трёх частей:
if let— «если в коробке что-то есть, достань это»;age— имя для значения из коробки;= Int(typed)— опционал, который открывают.
У if let три правила:
- блок в фигурных скобках выполняется, только когда в коробке есть значение;
- имя
ageсуществует только внутри этих скобок, а после}его уже нет; - ветка
elseвыполняется, когда в коробкеnil, и её можно не писать.
В программе ниже результат Int(…) сначала кладут в константу, чтобы коробку было видно отдельно от её содержимого. Нажмите «Следующий шаг» и следите за константой n: она появляется только внутри фигурных скобок и только когда в коробке есть число.
1let first = Int("12")2if let n = first {3 print(n + 1)4} else {5 print("not a number")6}7let second = Int("12a")8if let n = second {9 print(n + 1)10} else {11 print("not a number")12}13print("done")
В тексте есть число, поэтому first — коробка с 12 внутри.
Виджет показал, когда константа n есть, а когда нет:
- при числе в коробке
if letзаводит константуnи выполняет первый блок; - при
nilконстанта не появляется и выполняется веткаelse; - после закрывающей скобки
nисчезает в обоих случаях.
Здесь картинка с коробкой неточна. Настоящий подарок вынимают из коробки, и она пустеет. А if let копирует значение в новую константу: first до конца программы хранит Optional(12).
На собеседовании if let называют безопасным извлечением. Программа не может аварийно завершиться на такой проверке: при nil она пропускает блок и выполняет else, если он есть.
Другие формы if let
Краткая запись
Если у опционала уже есть имя, его можно не повторять. Запись if let score значит то же, что if let score = score:
let score: Int? = 90
if let score {
print("score:", score) // score: 90
}Внутри фигурных скобок score — уже число 90 типа Int. За скобками то же имя снова означает опционал Int?.
Два опционала сразу
Через запятую в одном if открывают несколько коробок. Первый блок выполнится, только если значения есть во всех:
let width = Int("4")
let height = Int("five")
if let width, let height {
print("area:", width * height)
} else {
print("need two numbers") // need two numbers
}В тексте "five" числа нет, поэтому коробка height пуста. Одной пустой коробки хватает, чтобы программа пошла в ветку else.
Частая ошибка
Имя из if let использовали после закрывающей скобки:
if let age = Int(typed) {
print(age)
}
print(age + 1) // ✗error: cannot find 'age' in scopeКонстанта age существует только внутри фигурных скобок if let, поэтому в последней строке такого имени нет. Код, которому нужно значение, пишите внутри этих скобок.
Главное
if let age = Int(typed)открывает опционал: если в нём есть значение, заводит константуageи выполняет блок.- При
nilблок не выполняется, а веткаelse, если она есть, выполняется. - Имя из
if letсуществует только внутри фигурных скобок, а сам опционал после проверки не меняется. - Краткая запись
if let scoreоткрывает опционал с тем же именем, а через запятую открывают несколько опционалов сразу.