Перейти к содержимому
Теория · Опционалы · урок 3 из 8

if let

Сравнение с nil говорит, пуста ли коробка, но не открывает её. Чтобы воспользоваться подарком, коробку открывают. Если внутри что-то есть, подарок достают и работают с ним, а если пусто — делают что-то другое. В Swift if let открывает опционал так:

SWIFT
let typed = "25"
if let age = Int(typed) {
    print("next year:", age + 1) // next year: 26
} else {
    print("not a number")
}

Давайте разберём программу по строкам:

  1. Int(typed) превращает текст в Int?, и в этой коробке лежит 25.
  2. if let age = … открывает коробку. Внутри есть число, поэтому Swift заводит константу age типа Int со значением 25 и выполняет блок в фигурных скобках.
  3. age — обычное целое число, и age + 1 складывается без ошибки: программа печатает next year: 26.
  4. Ветку 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: она появляется только внутри фигурных скобок и только когда в коробке есть число.

Вживуюif let открывает коробкушаг 1 из 7 · рамок: 1

В тексте есть число, поэтому first — коробка с 12 внутри.

Следите за n: она есть только внутри скобок и только при числе в коробке

Виджет показал, когда константа 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:

SWIFT
let score: Int? = 90
if let score {
    print("score:", score) // score: 90
}

Внутри фигурных скобок score — уже число 90 типа Int. За скобками то же имя снова означает опционал Int?.

Два опционала сразу

Через запятую в одном if открывают несколько коробок. Первый блок выполнится, только если значения есть во всех:

SWIFT
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 использовали после закрывающей скобки:

SWIFT
if let age = Int(typed) {
    print(age)
}
print(age + 1) // ✗
TEXT
error: cannot find 'age' in scope

Константа age существует только внутри фигурных скобок if let, поэтому в последней строке такого имени нет. Код, которому нужно значение, пишите внутри этих скобок.

Главное

  • if let age = Int(typed) открывает опционал: если в нём есть значение, заводит константу age и выполняет блок.
  • При nil блок не выполняется, а ветка else, если она есть, выполняется.
  • Имя из if let существует только внутри фигурных скобок, а сам опционал после проверки не меняется.
  • Краткая запись if let score открывает опционал с тем же именем, а через запятую открывают несколько опционалов сразу.