Конструкция switch

Последнее обновление: 29.12.2017

Конструкция switch/case похожа на конструкцию if/else, так как позволяет обработать сразу несколько условий:

var num: Int = 22

switch num {
case 0:
    print("Переменная равна 0")
case 10:
    print("Переменная равна 10")
case 22:
    print("Переменная равна 22")
default:
    print("не удалось распознать число")
}

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

Если совпадение не будет найдено, то выполняется оператор default.

В данном случае так как переменная num равна 22, будет выполняться следующий блок case:

case 22:
    print("Переменная равна 22")

В других языках программирования, в которых также есть конструкция switch/case, обычно в конце блока case ставится оператор break для прерывания выполнения и выхода из блока switch/case. В Swift использовать оператор break в подобных случаях необязательно. Однако бывают случаи, когда мы не хотим обрабатывать какие-то определенные значения и просто хотим выйти из конструкции switch. В этом случае после оператора case или default можно указать оператор break:

var num: Int = 0

switch num {
case 0:
    print("Переменная равна 0")
case 10:
    break
case 22:
    print("Переменная равна 22")
default:
    break
}

В данном случае если num равно 10 или другому числу, отличному от 0 или 22, просто произойдет выход из switch.

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

let number = 5
switch number {
case 1:
    print("Number = 1")
case 2:
    print("Number = 2")
case _:
    print("Number не равно ни 1, ни 2, но это не точно")
}

Также мы можем сравнивать выражение не с одним значением, а с группой значений:

var num: Int = 20

switch num {
case 0, 10: 	// если num равно 0 или 10
    print("Переменная равна 0 или 10")
case 11..<20:	// если num в диапазоне от 11 до 20, не включая 20
    print("Переменная находится в диапазоне от 11 до 20")
case 20...30:	// если num в диапазоне от 20 до 30
    print("Переменная находится в диапазоне от 20 до 30")
default:
    print("не удалось распознать число")
}

Оператор case 0, 10 задает два сравниваемых значения 0 и 10 и срабатывает, если выражение равно одному из этих значений.

Оператор case 11..<20 определяет целый диапазон значений от 11 до 20 (не включая 20) и срабатывает, если выражение равно значению из этого диапазона.

Оператор case 20...30 определяет целый диапазон значений от 20 до 30 (включая оба числа) и срабатывает, если выражение равно значению из этого диапазона.

В версии Swift 4 мы можем опускать одну границу диапазона:

let i = 8
switch i {
case ...<0:
    print("i - отрицательное число")
case 1...:
    print("i - положительное число")
case 0:
    print("i равно 0")
default:break
}

Кортежи в switch/case

Кроме выражений простых типов можно сравнивать кортежи:

let personInfo = ("Tom", 22)
switch personInfo {
case ("Bob", 33):
    print("Имя: Bob, возраст: 33")
case (_, 22):
    print("Имя: \(personInfo.0) и возраст: 22")
case ("Tom", _):
    print("Имя: Tom и возраст: \(personInfo.1)")
case ("Tom", 1...30):
    print("Имя: Tom и возраст от 1 до 30")
default:
    print("Информация не распознана")
}

Здесь кортеж personInfo последовательно сравнивается с тремя кортежами в операторах case. При сравнении мы можем задать полный кортеж:

case ("Bob", 33):
    print("Имя: Bob, возраст: 33")

Либо мы также можем опустить один из элементов кортежа, подставив вместо него знак подчеркивания _:

case (_, 22):
    print("Имя: \(personInfo.0) и возраст: 22")

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

Для числовых данных мы также можем задать не точное значение, а диапазон значений:

case ("Tom", 1...30):
    print("Имя: Tom и возраст от 1 до 30")

В этом случае второй элемент кортежа должен находиться в диапазоне от 1 до 30.

В использованной нами выше конструкции switch/case сравниваемому выражению соответствуют аж три оператора case - второй, третий и четвертый, но выполняться будет только первый из них.

Но если мы хотим, чтобы также выполнялся и следующий оператор case (или оператор default), то в конце предыдущего блока case следует использовать оператор fallthrough:

let personInfo = ("Tom", 22)
switch personInfo {
case ("Bob", 33):
    print("Имя: Bob, возраст: 33")
case (_, 22):
    print("Имя: \(personInfo.0) и возраст: 22")
	fallthrough
case ("Tom", _):
    print("Имя: Tom и возраст: \(personInfo.1)")
default:
    print("Информация не распознана")
}

Связывание значений

Механизм связывания значений позволяет определить в блоках case переменные и константы, значения которых будут связаны со значением сравниваемого выражения:

let number = 5
switch number {
case 1:
    print("Number = 1")
case 2:
    print("Number = 2")
case let n:
    print("Number = \(n)")
}

В данном случае если значение number не равно 1 и 2, то оно передается константе n, которая используется в рамках своего блока case.

При этом привязка может выполняться к переменным и константам более сложных типов, например, кортежей:

let personInfo = ("Tom", 22)
switch personInfo {
case (let name, 22):
    print("Имя: \(name) и возраст: 22")
case ("Tom", let age):
    print("Имя: Tom и возраст: \(age)")
case let (name, age):
    print("Имя: \(name) и возраст: \(age)")
}

Если второй элемент в personInfo равен 22, то срабатывает блок

case (let name, 22):
    print("Имя: \(name) и возраст: 22")

Здесь переменная name получает значение первого элемента из кортежа personInfo.

Причем в этой конструкции не используется блок default, так как блок

case let (name, age):
    print("Имя: \(name) и возраст: \(age)")

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

Оператор where

Если при выполнении блока case мы хотим задать дополнительные условия, то в этом случае нам поможет оператор where. Например:

let i = 8
switch i {
case let k where k < 0:
    print("i - отрицательное число")
case let k where k > 0:
    print("i - положительное число")
case 0:
    print("i is 0")
default:break
}

Пример с кортежами:

let personInfo = ("Tom", 22)
switch personInfo {

case ("Tom", _) where personInfo.1 > 10 && personInfo.1 < 15:
    print("Имя: Tom и возраст от 10 до 15")
	
case ("Tom", _) where personInfo.1 >= 20:
    print("Имя: Tom и возраст от 20 и выше")
	
default:
    print("Неизвестно")
}

Выражения where определяют дополнительные условия. И если они не выполняются, то соответственно блок case тоже не выполняется.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850