Swift управление потоками Часть 3

image

Приветствуем вас в третьей части нашей мини-серии по Swift, в которой вы узнаете как использовать булевые пеерменные и управлять потоками. Данный материал является переводом tutorial с сайта raywenderlich.com.

Это будет финальная часть мини-серии. Первые две части можно найти на нашем сайте: Часть 1: Swift: выражения,переменные и константы. или Часть 2: Swift: Типы и операции

В терминологии компьютерного программирования возможность сказать компьютеру что делать в различных ситуациях называется управление потоками (control flow).

В этой части мини-серии вы узнаете как принимать решения и повторять задачи в ваших программах используя синтаксис управления потоками. Вы также узнаете о булевых переменных, которые оперируют всего двумя значениями true и false, а также как можно с их помощью сравнивать данные.

С чего начать

К этому моменту вы уже должны понимать что из себя представляют некоторые типы данных, например такие, как Int, Double и String. Сейчас вы познакомитесь с другим типом данных, который позволит вам сравнивать значения применяя операторы сравнения.

Когда выполняется сравнение, например поиск большего из двух чисел, ответ представляет собой либо правда , либо ложь. Swift имеет тип данных специально предназначенный для таких целей. Он называется Bool, что является сокращением от слова Boolean. Само понятие булевого числа было введено в математику Джорджем Булем, предложившим концепцию true или false.

Вот как используются Boolean в Swift:

let yes = true // Подразуемвается что это тип Bool
let no = false // Подразуемвается что это тип Bool

Вообще говоря, булевая пеерменная может иметь только два значения: правда или ложь, которые обозначаются ключевыми словами true или false, соответственно. В примере выше использовались эти ключевые слова для присвоения значения константам.

Булевые операторы

Булевый тип данных в основном используется для сравнения значений. Например, у вас есть два значения и вы хотите знать равны ли они между собой: либо эти значения равны (true), либо они различны (false).

В Swift вы можете выполнить это используя оператор равенства, который обозначается ==:

let doesOneEqualTwo = (1 == 2)

Swift подразумевает, что doesOneEqualTwo это тип Bool. Совершенно очевидно, что 1 не равно 2 и поэтому,doesOneEqualTwo будет присвоено значение false

Аналогично, если два числа не равны можно использовать оператор !=:

let doesOneNotEqualTwo = (1 != 2)

В этом случае сравнение будет true, так как 1 не равно 2, поэтому doesOneNotEqualTwo будет присвоено значение true

Префикс оператора ! также называемый оператор отрицания, переключает true на false, а false на true. То же самое можно записать иначе:

let alsoTrue = !(1 == 2)

Рассмотрим это выражение шаг за шагом: 1 не равно 2, поэтому (1 == 2) это false и тогда ! переключает false на true.

Еще два оператора позволят вам определить если число больше чем (>) или меньше чем (<) другое число. Совершенно точно, что вы знакомы с этими оперторами из школьного курса математики.

let isOneGreaterThanTwo = (1 > 2)
let isOneLessThanTwo = (1 < 2)

Это не наука о космических ракетах, поэтому каждому будет понятно, что константа isOneGreaterThanTwo будет равна false, а константа isOneLessThanTwo будет равнаtrue.

Есть еще оператор, который позволяет проверять если значение меньше или равно другому значению: <=. Это комбинация < и ==, и поэтому она возвращает true если первое значение либо меньеше, чем второе значение, либо равно ему.

Аналогично работает оператор >=, которые позволяет выполнить проверку является ли значение больше или меньше другого.

Булевая логика

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

Одним из способов объединения условий является использование оператора AND. Когда вы используете AND вместе с булевыми значениями, результатом будет другое булевое значение. Если оба входящих булевых значения true, тогда результатом будет другое булевое значение true. В противном случае результатом будет false.

george_boole

В Swift булевый оператор AND обозначается как &&:

let and = true && true

В этом случае and будет присвоено значение true. Если бы любое значение справа было false,тогда and было бы присвоено значение false.

Другой способ объединения условий это использование оператора OR. Когда вы используете OR вместе с двумя булевыми значениями, результат будет true, если один из входящих булевых значений является true. Только если оба входящих значения являются false, результат будее тоже false.

В Swift булевый оператор OR обозначается как ||:

let or = true || false

В этом случае or будет true. Если оба значения справа были false, тогда значениеor было бы false. Если бы оба значения были true, тогда значение or стало быtrue.

В Swift булевая логика обычно применяется к нескольким условиям. Например:

let andTrue = 1 < 2 && 4 > 3
let andFalse = 1 < 2 && 3 > 4

let orTrue = 1 < 2 || 3 > 4
let orFalse = 1 == 2 || 3 == 4

Каждая из этих проверок предусматривает два различных условия, объединенных либо оператором AND, либо оператором OR.

Также допускается использовать булевую логику для объединения более чем двух условий. Например вы можете формировать сравнения так:

let andOr = (1 < 2 && 3 > 4) || 1 < 4

Когда вы заключаете скобками часть выражения, вы определяете порядок его выполнения. Вначале, Swift выполнит выражение внутри скобок, а затем выполнит все выражение целиком:

1. (1 < 2 && 3 > 4) || 1 < 4
2. (true && false) || true
3. false || true
4. true

Равенство строк

Иногда вы хотите определит равны ли две строки друг другу. Например, задачей в детской игре может быть правильное определение названий животных, изображенных на фотографиях.

В Swift вы можете сравнивать строки используя стандартный оператор равенства ==, точно таким же способом каким мы ранее сравнивали числа. Например:

let guess = "dog"
let dogEqualsCat = guess == "cat"

dogEqualsCat имеет булевое значение, которое в данном случае равно false, потому, что слово "dog" не равно слову "cat".

Точно так же как и с числами, вы можете сравнивать не только равны ли строки, но также определять больше одна из строк или меньше, чем другая. Например:

let order = "cat" < "dog"

Такой сиснтаксис проверит если одна из строк находится ранее другой в алфавитном порядке. В этом случае значение order равно true потому, что "cat" по алфавиту находится до "dog".

Условный оператор if

Первый и самый общий способ контроля потока в программе это использование условного оператора if (или выражения if), который позволяет программе делать что-то только если выполняется определенное условие как true. Например, рассмотрим следующий пример:

if 2 > 1 {
  print("Yes, 2 is greater than 1.")
}

Это самый простой пример использования оператора if. Если условие выполняется как true, тогда оператор будет выполнять код между фигурными скобками. Если условие выполняется как false, тогда оператор не будет выполнять код между фигурными скобками.

Вы можете изменить оператор if включив в него возможность выполнения кода, если условие ыполняется как false. Для этого используется оператор else. Например:

let animal = "Fox"
if animal == "Cat" || animal == "Dog" {
  print("Animal is a house pet.")
} else {
  print("Animal is not a house pet.")
}

В данном случае если значение animal равно либо "Cat" либо "Dog", тогда оператор выполнит первый блок кодв. Если значениеanimal не равно "Cat" или "Dog", тогда оператор выполнит блок кода, заключенный внутри else, напечатав следующее в дебаггере:

Animal is not a house pet.

Но, с условным оператором if вы можете еще больше, чем в предыдущем примере. Иногда вы хотите проверить одно условие, на соответстиве нескольким. Для этого используется оператор else-if, с помощью которого можно вложить еще один оператор if в оператор else, относящийся к предыдущему условному оператору if.

Например, можно записать код так:

let hourOfDay = 12
var timeOfDay = ""

if hourOfDay < 6 {
  timeOfDay = "Early morning"
} else if hourOfDay < 12 {
  timeOfDay = "Morning"
} else if hourOfDay < 17 {
  timeOfDay = "Afternoon"
} else if hourOfDay < 20 {
  timeOfDay = "Evening"
} else if hourOfDay < 24 {
  timeOfDay = "Late evening"
} else {
  timeOfDay = "INVALID HOUR!"
}
print(timeOfDay)

В данном случае вложенные операторы if проверяют условия одно за другим, пока одно из них не выполнится как true. Только код, связанный с этим условием будет выполнен, независимо от того могут ли последующие условия else-ifвыполниться как true. Иными словам порядок проверки условий имеет значение!

Вы можете добавить условный оператор elseв конец для обработки случая, когда ни одно из условий не выполняется как true. В таком случае использование else является опциональным, если вы не нуждаетесь в нем. В использованном примере необходимо, чтобы переменная timeOfDay имела валидное значение времени, когда вы будете распечатывать его значение.

В этом прмиере условный оператор if получает время, выраженное в часах (числах) и конвертирует его в строку, представляющую описание времени дня, к которому это время относится. Работая с 24-х часовым форматом времени условный оператор проверяет последовательно одно услвоие за другим.

В коде выше переменная hourOfDay имеет значение 12. Поэтому, код будет печатать следующее сообщение:

Afternoon

Обратите внимание, что, хотя еще два условия hourOfDay < 20 и hourOfDay < 24 также выполняются как true, условный оператор выполнит только первый блок, чье условие соответствут true. В этом случае, выполнится блок с условием hourOfDay < 17.

Инкапсуляция переменных

Условный оператор if описывает новую концепцию пространства, которая является способом инкапсуляции переменных с помощью фигурных скобок.

Вообразите, что вы хотите подсчитать комиссию, которую взимает ваш клиент. Вот сделка, которую вы заключили:

Вы зарабатываете 25 долларов в час за 40 часов, и 50 долларов за каждый час сверх этого времени.

Используя Swift вы можете расчитать ваши платежи:

var hoursWorked = 45

var price = 0
if hoursWorked > 40 {
  let hoursOver40 = hoursWorked - 40
  price += hoursOver40 * 50
  hoursWorked -= hoursOver40
}
price += hoursWorked * 25

print(price)

Этот код получает количество часов и проверяет, превышает ли это число 40 часов. Если это так, код считает количество часов сверх 40 и умножает его на 50 долларов, затем добавляет результат к цене. Далее код вычитает количество часов превышающих 40 из отработанных часов. Осташееся время умножается на 25 долларов и добавляется к цене.

В примере выше результата должен быть следующим:

1250

hoursOver40 объявляет новую константу, которую можно использовать внутри оператора if. Но, что случится, если вы попробуете использовать ее в конце кода, за пределами оператора if?

// ...

print(price)
print(hoursOver40)

Результат будет следующим:

error: MyPlayground.playground:8:7: error: use of unresolved identifier 'hoursOver40'
print(hoursOver40)
  ^~~~~~~~~~~

Эта ошибка информирует вас что вы можете использовать константу hoursOver40 в пространстве, в котором эта константа была объявлена (создана). В этом случае, условный оператор if создает новое пространство, так, что когда это пространство заканчивается, вы не можете больше испоьзовать эту константу.

В любом случае, каждое пространство может использовать переменные и константы объявленные в своем родительством пространстве. В примере выше пространство внутри оператора if использует переменные price и hoursWorked, которые были созданы в родительском пространстве.

Тернарный условный оператор

Тернарный условный оператор получает условие и возвращает одно из двух значений, в зависимости от того, что было результатом выполнения условия: true or false:

(<CONDITION>) ? <TRUE VALUE> : <FALSE VALUE>

Рассмотрим пример в котором надо определить минимальное из двух переменных:

let a = 5
let b = 10

let min: Int
if a < b {
  min = a
} else {
  min = b
}

Благодаря тернарному оператору вы можете переписать этот код по-другому:

let a = 5
let b = 10

let min = a < b ? a : b

Если условие a < b является true, тогда результатом будет присвоение константе min значения a; если false, то результатом будет значение b.

Тернарный оператор следует применять с осторожностью. Его краткость может стать причиной написания трудночитаемого кода.

Циклы

Циклы это способ выполнять код многократно. В самом начале этого раздела вы узнаете о цикле while.

Циклы While

Цикл while повторяет блок кода пока некоторое условие выполняется как true.

Цикл while создается следующим образом:

while <CONDITION> {
  <LOOP CODE>
}

Во время каждой итерации цикл проверяет выполнение условия. Если условие выполняется как true, тогда цикл выполняется и переходит к следующей итерации. Если условие выполняется, как false, тогда цикл останавливается, Также, как и условный оператор if, цикл while создает пространство.

Простейший цикл while:

while true {
}

Этот цикл while, который никогда не закончится, потому, что условие всегда будет true. Бесконечный цикл может не стать причиной падения вашей программы, но это может с высокой вероятностью "повесить" ваш компьютер.

Force quit

Вот более реальный пример цикла while:

var sum = 1

while sum < 1000 {
  sum = sum + (sum + 1)
}

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

Цикл выполняется следующим образом:

While Loop iteration

После девяти итераций значение переменой sum станет равно1023, поэтому условие выполнения цикла sum < 1000 станет false. После этого выполнение цикла остановится.

Циклы Repeat-while

Это вариант цикла whileназванный цикл repeat-while. Отличие от цикла while состоит в том, что условие выполнения цикла оценивается в конце выполнения цикла, а не в начале.

Цикл repeat-while конструируется следующим образом:

repeat {
  <LOOP CODE>
} while <CONDITION>

Вот предыдущий пример, но с сипользованием цикла repeat-while:

sum = 1

repeat {
  sum = sum + (sum + 1)
} while sum < 1000

В этом примере результат будет точно такой-же. При этом, такое совпадение может быть не всегда.

Рассмотрим следующий пример выполнения цикла while:

sum = 1

while sum < 1 {
  sum = sum + (sum + 1)
}

А сейчас рассмотрим соответствующий цикл repeat-while, который использует для выполнения точно такое-же условие:

sum = 1

repeat {
  sum = sum + (sum + 1)
} while sum < 1

В случае с регулярным цикло while, условие sum < 1 равна false будет выполнено сразу на старте цикла, Это значит, что код в теле цикла не будет выполнен. Значение переменной sum будет равно 1 потому, что цикл не будет выполнен ни разу.

В случае же с циклом repeat-while, переменная sum будет равна 3, потому, что цикл будет выполнен один раз.

Прерывание цикла

Иногда вы хотите прервать цикл ранее, чем он будет закончен. Вы можете использовать для этого выражение break, которое немедлено остановит выполнение цикла и продолжит выполнение кода после цикла.

Например, рассмотрим следующий код:

sum = 1

while true {
  sum = sum + (sum + 1)
  if sum >= 1000 {
    break
  }
}

В этом примере условие выполнения цикла равно true, так что цикл может выполняться бесконечно. Однако, наличие выражения break означает, что цикл while будет остановлен как только значение sum станет больше или равно 1000.

Продвинутое управление потоками

В этом разделе вы продолжите знакомиться с тем, как контролировать выполнение потока. Вы узнаете о цикле, который называется цикл for.

Диапазоны

До того, как погрузиться в изучение цикла for, вам необходимо знать о ClosedRange - закрытом диапазоне and Range - полуоткрытом диапазоне типах, которые позволяют представлять последовательности чисел.

Во-первых, существуют закрытые диапазоны:

let closedRange = 0...5

Три точки (...) сигнализируют что этот диапазон закрытый, что означает диапазон числе от 0 до 5, включая 0 и 5: (0, 1, 2, 3, 4, 5).

Во-вторых, существуют полуоткрытые диапазоны:

let halfOpenRange = 0..<5

В этом случае заменим три точки на две точки и знак меньше (..<). Полуоткрытый диапазон значит диапазон от 0 до 5, включая 0, но не включая 5: (0, 1, 2, 3, 4).

Оба закрытый и полуоткрытый диапазоны должны всегда быть возрастающими. Другими словами, второе число диапазона должно быть всегда больше или равно первому.

Диапазоны обычно используют для циклов for и выражения switch.

Цикл For

Теперь, когда вы знаете немного о диапазонах, самое время взглянуть на цикл for. Этот цикл используется для выполнения кода определенное число раз.

Конструкция цикла for выглядит так:

for <CONSTANT> in <RANGE> {
  <LOOP CODE>
}

Оператор for начинается со слова for. Далее последовательно указываются: имя константы, слово in и диапазон повторений цикла. Например:

let count = 10
var sum = 0

for i in 1...count {
  sum += i
}

Цикл for выполняется в диапазоне от 1 до значения константы count. В первом выполнении цикла i будет равно первому элементу диапазона - 1. На каждом повторении i будет увеличиваться на единицу, до тех пор, пока не будет равной count, после чего цикл будет выполнен последний раз.

Если вы используете полуоткрытый диапазон, последняя итерация будет при значении i равном count - 1.

Внутри цикла вы добавляете i к переменной sum. Эта операция повторяется 10 раз , таким образом выполняется последовательно сложение 1 + 2 + 3 + 4 + 5 + ... до тех пор пока i не будет равно 10.

На рисунке ниже изображены значения константы i и переменной sum для каждой итерации:

Итерации цикла for

Константа i видима только внутри пространства цикла for, что значит, что эта константа не доступна за пределами цикла.

В случае, если вы не хотите использовать в цикле константы вовсе, вы можете использовать знак нижнего подчеркивания (_) для укзания что игнооируете ее (константу). Например:

sum = 1
var lastSum = 0

for _ in 0..<count {
  let temp = sum
  sum = sum + lastSum
  lastSum = temp
}

Этот код не имеет константы в цикле, цикл просто выполняется определенное число раз. В этом случае диапазон начинается от 0 и заканчивается значением count, при этом диапазон полуоткрытый. Таким способом обычно записываются циклы, которые выполняются определенное число раз.

Также возможно выполнить только те итерации, которые соответствуют определнному условию. Например, представим, что вы хотите вычислить сумму только нечетных чисел:

var sum = 0
for i in 1...count where i % 2 == 1 {
  sum += i
}

Цикл выше содержит оператор where. Благодаря этому цикл будет выполнять код в диапазоне от 1 до count, но только в том случае, когда условие предусмотренное where будет true. В этом случае это будет, когда значение i является нечетным числом.

Оператор Continue

Иногда вым может понадобится пропустить итерацию цикла в определенном случае, без прерывания самого цикла целиком. Вы можете сделать это с помощью оператора continue, который немедленно закончит текущую итерацию и перейдет к следующей.

Использование continue вместо простого where предпочтительнее, когда вам необходим высокоуровневый контроль над исполнением кода.

Например рассмотрим сетку 8х8, в которой каждая ячейка содержит значение номера ряда умноженого на колонку:

full_board

Это очень похоже на таблицу умножения, не правда ли?

Скажем, вы хотите расчитать сумму всех ячеек за исключением тех, которые расположены на четных рядах:

first_board_example

С помощью цикла for эту задачу можно решить следующим образом:

sum = 0

for row in 0..<8 {
  if row % 2 == 0 {
    continue
  }

  for column in 0..<8 {
    sum += row * column
  }
}

Когда остаток от деления номера ряда на 2 равен 0, тогда этот ряд четный. В этом случае continue заставит цикл for перепрыгнуть на следующий ряд.

Также, как и break, continue работает с обоими циклами - for и while.

Оператор Switch

Еще один способ управления потоками осуществляется через использование оператора switch, который позволяет вам выполнять различные части кода в зависимости от значение переменной или константы.

Вот очень простой оператор switch, который обрабатывает целые числа:

let number = 10

switch number {
case 0:
  print("Zero")
default:
  print("Non-zero")
}

После выполнение кода в консоли будет напечатано:

Non-zero

Целью оператора switch было определение является ли число нулем.

Для обработки конкрентного значения вы используете case, представляющее значение, которое вы хотите сравнить с получаемым значением, в даном случае это 0. Также вы используете default, чтобы назначить действие, если оператор switch получит любое другое число, отличное от 0.

Вот другой пример использования switch:

switch number {
case 10:
  print("It's ten!")
default:
  break
}

В этом примере вы проверяете является ли значение переменной или константы равным 10, и, если это так, в консоли выводится соответствующее сообщение. Для значений, отличных от 10 никаких действий не предусмотрено. Когда вы не хотите выполнения какого-либо действия, или вы хотите определить дефолтное состояние для выполнения кода, можно использовать оператор break. Это подскажет Swift'у что вы не написали здесь никакго кода и никаких действий выполняться не будет. сase никогда не должен оставаться пустым, поэтому необходимо писать код, даже если этим кодом будет оператор break!

Оператор switch работает с любыми типами данных! Вот пример обработки для строк:

let string = "Dog"

switch string {
case "Cat", "Dog":
  print("Animal is a house pet.")
default:
  print("Animal is not a house pet.")
}

После выполнения кода в консоле появится сообщение:

Animal is a house pet.

В этом примере, вы передаете два значения для одного оператора case, поэтому код будет выполняться в случае, если переданое значение будет либо "Cat", либо "Dog".

Продвинутые действия с оператором Switch

Вы можете также передать вашему оператору switch более, чем один case. В предыдущем разделе вы видели, что оператор if использует множество вложенных операторов else-if для конвертирования времени. Вы можете переписать это более кратко, с использванием оператора switch:

let hourOfDay = 12
var timeOfDay = ""

switch hourOfDay {
case 0, 1, 2, 3, 4, 5:
  timeOfDay = "Early morning"
case 6, 7, 8, 9, 10, 11:
  timeOfDay = "Morning"
case 12, 13, 14, 15, 16:
  timeOfDay = "Afternoon"
case 17, 18, 19:
  timeOfDay = "Evening"
case 20, 21, 22, 23:
  timeOfDay = "Late evening"
default:
  timeOfDay = "INVALID HOUR!"
}

print(timeOfDay)

Выполнение этого кода выведет в консоль сообщение:

Afternoon

Помните диапазоны? Вы можете использовать диапазоны в операторе switch. Можно переписать этот код еще более кратко:

var timeOfDay2 = ""

switch hourOfDay {
case 0...5:
  timeOfDay2 = "Early morning"
case 6...11:
  timeOfDay2 = "Morning"
case 12...16:
  timeOfDay2 = "Afternoon"
case 17...19:
  timeOfDay2 = "Evening"
case 20..<24:
  timeOfDay2 = "Late evening"
default:
  timeOfDay2 = "INVALID HOUR!"
}

print(timeOfDay2)

Также можно сопоставлять условия, основанные на свойствах значения. Как вы узнали ранее в первой части этой серии, вы можете использовать оператор модуль для определения является ли целое число четным или нечетным. Например так:

switch number {
case let x where x % 2 == 0:
  print("Even")
default:
  print("Odd")
}

Выполнение этого кода выведет в консоль сообщение:

Even

Оператор switch использует синаксис let-where, который означает, что case будет выполненен только если определенное условие будет выполняться как true. Часть синтаксиса let связывает значение и имя, в то время как оператор where обеспечивает булевое условие, которое должно выполняться как true для выполнения case. В этом примере case выполняется в случае, если значение четное, т.е. если значение остатка от деления на 2 равно 0.

Этот метод, с помощью которого вы можете сравнивать числа еще называют паттерн сравнения.

В предыдущем примере была использована в общем-то ненужная константа х, фактически это еще одно наименование для number. Вы можете использовать number в конструкции whereи заменить константу х на знак нижнего подчеркивания.

switch number {
case _ where number % 2 == 0:
  print("Even")
default:
  print("Odd")
}

Частичное сравнивание

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

let coordinates = (x: 3, y: 2, z: 5)

switch coordinates {
case (0, 0, 0): // 1
  print("Origin")
case (_, 0, 0): // 2
  print("On the x-axis.")
case (0, _, 0): // 3
  print("On the y-axis.")
case (0, 0, _): // 4
  print("On the z-axis.")
default:        // 5
  print("Somewhere in space")
}

Этот оператор switch использует частичное сравнивание. Вот что происходит в коде, по-порядку:

  1. Точное соответствие case в котором значение (0, 0, 0). Это центр 3D координат.
  2. Совпадение y=0, z=0 и любое значение x. Это координата по оси х.
  3. Совпадение x=0, z=0 и любое значение y. Это координата по оси y.
  4. Совпадение x=0, y=0 и любое значение z. Это координата по оси z.
  5. Совпадение с остальными координатами.

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

switch coordinates {
case (0, 0, 0):
  print("Origin")
case (let x, 0, 0):
  print("On the x-axis at x = \(x)")
case (0, let y, 0):
  print("On the y-axis at y = \(y)")
case (0, 0, let z):
  print("On the z-axis at z = \(z)")
case let (x, y, z):
  print("Somewhere in space at x = \(x), y = \(y), z = \(z)")
}

В данном случае используется синтаксис let для извлечения соответствующих значений. Затем в консоле выводится значение с помощью строковой интерполяции.

Обратите внимание на то, что в данном случае отсутствует дефолтное значение для оператора switch. Это потому, что последний case по сути является тем самым дефолтным значением. Он соответствуетлюбому значениям, которые не соответствуют предыдущим caseам. В switch нет необходимости в определении значения дефолтного case, если предусмотрены все возможные значения.

Также стоит обратить внимание на то, что правила синстаксиса позволяют указывать один оператор let для всех связанных значений кортежа: let (x, y, z) это то же самое, что (let x, let y, let z).

Таким образом, можно, используя тот же самый синтаксис let-where, записать код с более комплексным решением, например так:

switch coordinates {
case let (x, y, _) where y == x:
  print("Along the y = x line.")
case let (x, y, _) where y == x * x:
  print("Along the y = x^2 line.")
default:
  break
}

Как вы видите в данном случае сравнивается "y равный x" и "y равный квадрату x".

На этом мини-серия по Swift закончена. Желаем Вам успехов в изучении этого замечательного языка.

Источник