Конструкция 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 }
Кроме выражений простых типов можно сравнивать кортежи:
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.
Если при выполнении блока 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 тоже не выполняется.