Swift. Оператор ветвления switch

From AsIsWiki
Revision as of 08:59, 13 April 2022 by Alex (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Назад · Оглавление · Дальше


Contents

Синтаксис

switch Any {
    case Any, Any ...: // блок кода
    ...
    default:  // блок кода по умолчанию
}

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

Блок default выполняет действие для значений, не охваченных блоками case.

Определение четных и нечетных чисел:

var a = 5

switch a {
    case 1,3,5,7: print("odd")
    case 2,4,6,8: print("even")
    default:
        assert(false, "\(a) вне диапазона: 1...8")
}

Консоль:
odd

Диапазоны в операторе switch

Проверка числа на вхождение в различные диапазоны:

var mark = 4

switch mark {
    case 1..<3: print("Экзамен не сдан")
    case 3:     print("Требуется решение дополнительного задания")
    case 4...5: print("Экзамен сдан")
    default:
        assert(false, "Указана некорректная оценка")
}

Определение знака числа:

var a = -10

switch a {
    case ..<0: print("-")
    case 0...: print("+")
    default: break
}

// или так:

switch a {
    case _ where a < 0: print("-")
    case _ where a >= 0: print("+")
    default: break
}

Консоль:
-

Кортежи в операторе switch

Проверка значения кортежа на вхождение в диапазон:

var a = (7, "")

switch a {
    case (3...9, _): print("Диапазон: 3-9")
    case (0...5, _): print("Диапазон: 0-5")
    default:
        print("Значение вне диапазона.")
}

Консоль:
Диапазон: 3-9

Проверка сообщений сервера:

var answer: (code: Int, message: String) = (code: 404, message: "Page not found")

switch answer {
    case (100..<400, _): print(answer.message)
    case (400..<500, _): assert(false, answer.message)
    default:
        print( "Получен некорректный ответ" )
}

Консоль:
Assertion failed: Page not found

Распределение пони по вольерам:

var pony = ("белый", 2.15)  // вес в центнерах

switch pony {
    case ("чёрный", 0..<2):                 print("Вольер 1")
    case ("белый", 0..<2):                  print("Вольер 2")
    case ("чёрный", 2...), ("белый", 2...): print("Вольер 3")
    default:
        print("Вольер 4")
}

Консоль:
Вольер 3

Ключевое слово where

where - проверка дополнительного условия в case.

Например, в третьем вольере не может быть больше 5 пони:

var ponyCount = 3

switch pony {
    case ("чёрный", 0..<2):                    print("Вольер 1")
    case ("белый", 0..<2):                     print("Вольер 2")
    case ("чёрный", 2...) where ponyCount < 5,
         ("белый", 2...) where ponyCount < 5:  print("Вольер 3")
    default:
        print("Вольер 4")
}

Консоль:
Вольер 3

Проверка значения "a" с учетом значения "b":

var a = 2
var b = 3

switch a {
    case 1 where b == 3:     print("1")
    case 2 where b == a:     print("2")
    case 1...3 where b != a: print("3")
    default:
        break
}

Консоль:
3

Проверка кортежа:

var a = ("z", Double.pi)

switch a {
    case ("x", 0..<2), ("m", 0): print("xm")
    case ("y", 2...3):           print("y")
    case ("z", _) where a.1 > 3: print("z")
    default:
        break
}

Консоль:
z

Подавление основного параметра в case:

var a = 5

switch a {
    case _ where a % 2 != 0: print(a, "odd")
    case _ where a % 2 == 0: print(a, "even")
    default:
        break
}

Консоль:
5 odd

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

В заголовке case-блока объявляется локальный параметр,
который можно использовать после where и в теле case-блока.

Например, в третий вольер допускаются пони с весом без дробной части:

var pony = ("белый", 2.0)  // вес в центнерах

var ponyCount = 3

switch pony {
    case ("чёрный", 0..<2): print("Вольер 1")
        
    case ("белый", 0..<2):  print("Вольер 2")
        
    case ("чёрный", let weight) where
            weight >= 2 &&
            weight.truncatingRemainder(dividingBy: 1) == 0 &&
            ponyCount < 5,
         
         ("белый", let weight) where
            weight >= 2 &&
            weight.truncatingRemainder(dividingBy: 1) == 0 &&
            ponyCount < 5:
        
        print("Вольер 3. Вес пони \(weight) центнера")
        
    default: print("Вольер 4")
}

Консоль:
Вольер 3. Вес пони 2.0 центнера

Константа weight - связанный параметр (содержит связанное значение).

Упрощаем код, объявив сразу два связанных параметра:

switch pony {
    case ("чёрный", 0..<2): print("Вольер 1")
        
    case ("белый", 0..<2):  print("Вольер 2")
        
    case let (color, weight) where
            (color == "чёрный" || color == "белый") &&
            weight >= 2 &&
            weight.truncatingRemainder(dividingBy: 1) == 0 &&
            ponyCount < 5:
        
        print("Вольер 3. Вес пони \(weight) центнера")
        
    default: print("Вольер 4")
}

Добавляем связанное значение в пример с кортежем:

var a = ("z", Double.pi)

switch a {
    case ("x", 0..<2), ("m", 0):       print("xm")
    case ("y", 2...3):                 print("y")
    case ("z", let num) where num > 3: print("z")
    default:
        break
}

Добавляем второе связанное значение:

switch a {
    case ("x", 0..<2), ("m", 0): print("xm")
    case ("y", 2...3):           print("y")
        
    case let(ch, num) where (ch == "z" || ch == "k") && num > 3: print("z")
        
    default: break
}

// ch, num - локальные параметры (содержат значения элементов кортежа)

Оператор break в конструкции switch-case

Если case-блок не имеет исполняемого кода, то в нем необходимо указать оператор break.
Это требуется для корректного завершения работы оператора switch.

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

Ключевое слово fallthrough

Если требуется выполнить следующий по порядку case (без проверки значения):

var a = 2

switch a {
    case 1: print("1")
    case 2: print("2"); fallthrough
    case 3: print("3")
    case 4: print("4")
    default: break
}

Консоль:
2
3

Пример

typealias Operation = (operandOne:Float, operandTwo:Float, operation:Character)

let a: Operation = (operandOne:4.5, operandTwo:3.2, operation:"+")

switch a.operation {
    case "+": print(a.operandOne + a.operandTwo)
    case "-": print(a.operandOne - a.operandTwo)
    case "*": print(a.operandOne * a.operandTwo)
    case "/": print(a.operandOne / a.operandTwo)
    default: break
}



Назад · Оглавление · Дальше

Personal tools
Namespaces

Variants
Actions
Navigation
Tools