Основы Swift / 7.2. Инструкция switch 2


Видео


Привязывание значений
Кейс switch может проименовать значения подходящих им элементов во временные константы или переменные для использования в теле кейса. Это поведение известно как привязывание значений, так как значения связываются со временными константами или переменными внутри тела кейса.

Пример использует точку (x, y), выраженную кортежем типа (Int, Int), и определяет её положение на графике следующим образом:
Рисунок 7.2.1
@{7.2\1}
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
    print("on the x-axis with x value of \(x)")
case (0, let y):
    print("on the y-axis with y value of \(y)")
case let (x, y):
    print("somewhere else at (\(x), \(y))")
}
// Выводит "on the x-axis with x value of 2"
Инструкция switch определяет, находится ли точка на красной x-оси, на оранжевой y-оси или где-то ещё (не на оси).

Три кейса switch объявляют замещающие константы x и y, которые временно берут одно или несколько значений кортежа из anotherPoint. Первый кейс - case (let x, 0) - включает в себя любую точку с y-значением, равным 0, и присваивает x-значение временной константе x. Аналогично, второй кейс - case (0, let y) - включает в себя любую точку с x-значением, равным 0, и присваивает y-значение временной константе y. После объявления временных констант их можно использовать внутри кейса. Здесь они используются для вывода расположения точки.

Этот switch не содержит кейса default. Последний кейс - case let (x, y) объявляет кортеж из двух замещающих констант, которым могут соответствовать любые значения. Так как anotherPoint всегда является кортежем из двух значений, то этот кейс включает в себя все оставшиеся значения, так что кейс default не нужен, чтобы сделать инструкцию switch исчерпывающей.
where
Кейс switch может использовать блок where для проверки дополнительных условий.

Этот пример ниже определяет положение точки (x, y) на следующем графике:
Рисунок 7.2.2
@{7.2\2}
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
    print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    print("(\(x), \(y)) is just ome arbitary point")
}
// Печатает "(1, -1) is on the line x == -y"
Инструкция switch определяет, находится ли точка на зелёной диагональной линии, где x == 7, на фиолетовой диагональной линии, где x == y или не на какой.

Три кейса switch определяют замещающие константы x и y, которые временно берут оба значения кортежа из yetAnotherPoint. Эти константы используются как часть блока where для создания динамического фильтра. Кейс switch получает текущее значение point, только если условие блока where вычисляется в true для этого значения.

Последний кейс включает в себя все оставшиеся значения, так что кейс default не нужен для приведения инструкции switch к свойству исчерпываемости.
Составные кейсы
Множество кейсов switch, которые имеют общее тело, могут быть объединены с помощью написания нескольких паттернов после ключевого case с запятой между каждым из них. Если хотя бы один из паттернов совпадает, то и всё выражение считается совпавшим. Паттерны могут быть записаны на нескольких строках, если список длинный. Например:
@{7.2\3}
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
    print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
     "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
    print("\(someCharacter) is a consonant")
default:
    print("\(someCharacter) is not a vowel or a consonant")
}
// Напечатает "e is a vowel"
Первый кейс инструкции switch включает в себя все гласные буквы нижнего регистра в английском языке. Аналогично, второй кейс включает в себя все английские согласные нижнего регистра. В конце концов кейс default включает в себя все остальные символы.
Составные кейсы и привязывание значений
Первый кейс инструкции switch включает в себя все гласные буквы нижнего регистра в английском языке. Аналогично, второй кейс включает в себя все английские согласные нижнего регистра. В конце концов кейс default включает в себя все остальные символы.

Составные кейсы так же могут включать в себя привязки значений. Все паттерны составного кейса должны содержать один и тот же набор связок значений, а каждая связка должна иметь значение одного типа из всех паттернов в составном кейсе. Это означает, что неважно с какой частью составного кейса происходит совпадение, код в блоке кейса всегда будет иметь доступ к значению связок, а также что это значение всегда будет иметь один и тот же тип.
@{7.2\4}
let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let distance, 0), (0, let distance):
    print("On an axis, \(distance) from the origin")
default:
    print("Not on an axis")
}
// Напечатает "On an axis, 9 from the origin"
case выше имеет два паттерна: (let distance, 0), включающий точки на оси x, и (0, let distance), включающий точки на оси y. Оба паттерна включают привязку к distance, и distance имеет целый тип в обоих паттернах, что значит, что код в теле case всегда будет иметь доступ к значению distance.