Перейти к содержимому
Теория · Операторы · урок 5 из 7

Сравнение и логика

Кроме подсчётов, калькулятор Swift отвечает на вопросы «да или нет». Больше ли одно число другого? Совпадают ли две строки? Ответ — значение типа Bool: true или false. Такие ответы понадобятся, как только программа начнёт выбирать, что делать дальше.

Шесть операторов сравнения

Оператор сравнения берёт два значения и возвращает Bool:

  • == — равно;
  • != — не равно;
  • < и > — меньше и больше;
  • <= и >= — меньше или равно, больше или равно.
SWIFT
let age = 17
print(age >= 18) // false
print(age == 17, age != 17) // true false
let isAdult = age >= 18
print(isAdult) // false

Разберём по строкам:

  1. age >= 18 спрашивает, исполнилось ли 18. Ответ false.
  2. age == 17 даёт true, а age != 17 — false.
  3. Результат сравнения можно положить в константу: в isAdult лежит false.

Один знак = кладёт значение в константу или переменную, а два знака == сравнивают. Имя для Bool обычно читается как утверждение: isAdult, hasTicket.

Логические операторы

Представьте охранника на входе в клуб. Он пропускает гостя с билетом, если тому есть 18. Гостя из списка VIP пропускают и без билета. Чтобы записать такие правила, условия объединяют логическими операторами.

SWIFT
let hasTicket = true
let isVip = false
print(isAdult && hasTicket) // false
print(isVip || hasTicket) // true
print(!isVip) // true

И: &&

a && b даёт true, только когда верны обе части. Билет у гостя есть, но ему 17, поэтому isAdult && hasTicket — это false.

ИЛИ: ||

a || b даёт true, когда верна хотя бы одна часть. Гость не из списка VIP, но билет у него есть, поэтому isVip || hasTicket — это true.

НЕ: !

!a меняет ответ на противоположный. isVip равно false, значит, !isVip — это true.

Правая часть может не вычисляться

Охранник, увидев, что гостю нет 18, билет уже не спрашивает: ответ «нет» и так известен. Swift поступает так же. Если левая часть && равна false, правая не вычисляется вовсе. У || наоборот: при true слева правую часть Swift пропускает. Это называют вычислением по короткой схеме.

Короткая схема защищает от деления на ноль. Деление целого числа на ноль во время работы аварийно завершает программу, а проверка слева от && не даёт ему выполниться:

SWIFT
let total = 10
let count = 0
let isBig = count > 0 && total / count > 2
print(isBig) // false
  1. count > 0 — это false, ведь count равен нулю.
  2. Ответ && уже известен, и total / count не вычисляется.
  3. Программа печатает false и не завершается аварийно.

Здесь картинка с охранником неточна: живой охранник может спросить билет и у того, кого уже не пустил. Swift в таком случае правую часть не вычисляет никогда, и на этом держится защита от деления на ноль.

Вычисление по короткой схеме часто встречается на собеседовании. Обычно спрашивают, выполнится ли правая часть &&, если левая равна false.

Сравнение строк

Строки тоже сравнивают. Оператор == проверяет, что строки совпадают символ в символ. Операторы < и > сравнивают строки слева направо по номерам символов: у каждого символа в компьютере есть свой номер. Меньше та строка, у которой первый несовпавший символ имеет меньший номер. Для строчных латинских букв это совпадает с порядком в словаре, а в других случаях — не всегда:

  • "кот" == "Кот" — это false: заглавная и строчная буквы разные.
  • "apple" < "banana" — это true: первая буква a стоит раньше b.
  • "Zebra" < "apple" — тоже true: у заглавной Z номер меньше, чем у строчной a.
  • "10" < "9" — это true: строки сравниваются не как числа, а по символам, и у 1 номер меньше, чем у 9.
  • "ёж" < "жук" — это false: у буквы ё номер больше, чем у ж, и даже больше, чем у я.

Частая ошибка

Проверку на ноль поставили справа от деления:

SWIFT
let total = 10
let count = 0
let isBig = total / count > 2 && count > 0 // ✗
print(isBig)
TEXT
Fatal error: Division by zero

Левая часть && вычисляется первой, и деление на ноль аварийно завершает программу ещё до проверки. Проверка, которая защищает действие, должна стоять слева от &&.

Главное

  • Операторы ==, !=, <, >, <= и >= сравнивают два значения и дают Bool.
  • && даёт true, только когда верны обе части, || — когда верна хотя бы одна, а ! меняет ответ на противоположный.
  • Если ответ ясен по левой части && или ||, правая часть не вычисляется.
  • Строки сравниваются по символам: "Zebra" < "apple" и "10" < "9" — это true.