Spec-Zone .ru
спецификации, руководства, описания, API

Библиотека разработчика XCode

Разработчик

Swift язык программирования

iBook
На этой странице

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

Swift обеспечивает все знакомые операторы управления от подобного языкам C. Они включают for и while циклы для выполнения задачи многократно; if и switch операторы для выполнения различных ответвлений кода на основе определенных условий; и операторы такой как break и continue передать поток выполнения к другой точке в Вашем коде.

В дополнение к традиционному for цикл нашел в C, Свифт добавляет a for-in цикл, упрощающий выполнять итерации по массивам, словарям, диапазонам, строкам и другим последовательностям.

Swift switch оператор также значительно более мощен, чем его дубликат в C. Случаи a switch оператор не «проваливается» к следующему случаю в Swift, избегая общих ошибок C, вызванных путем без вести пропавших break операторы. Случаи могут соответствовать много различных образцов, включая соответствия интервала, кортежи и броски к определенному типу. Соответствующие значения в a switch случай может быть связан с временными константами или переменными для использования в организации случая, и сложные условия соответствия могут быть выражены a where пункт для каждого случая.

Для циклов

Swift обеспечивает два вида цикла, выполняющие ряд операторов определенное число времен:

  • for-in цикл выполняет ряд операторов для каждого элемента в последовательности.

  • for цикл выполняет ряд операторов, пока особому условию не удовлетворяют, обычно путем постепенного увеличения счетчика каждый раз концы цикла.

Для - В

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

Этот пример распечатывает первые несколько записей в пяти таблицах времен:

  • for index in 1...5 {
  • println("\(index) times 5 is \(index * 5)")
  • }
  • // 1 times 5 is 5
  • // 2 times 5 is 10
  • // 3 times 5 is 15
  • // 4 times 5 is 20
  • // 5 times 5 is 25

Выполняемая с помощью итераций последовательность является диапазоном чисел от 1 к 5, включительно, как обозначено при помощи закрытого оператора диапазона (...). Значение index установлен в первое число в диапазоне (1), и операторы в цикле выполняются. В этом случае цикл содержит только один оператор, распечатывающий запись от пяти таблиц времен для текущей стоимости index. После того, как оператор выполняется, значение index обновляется для содержания второго значения в диапазоне (2), и println функция вызвана снова. Этот процесс продолжается, пока конец диапазона не достигнут.

В примере выше, index константа, значение которой автоматически установлено в начале каждой итерации цикла. Также, это не должно быть объявлено, прежде чем это будет использоваться. Это неявно объявляется просто ее включением в объявление цикла без потребности в a let ключевое слово объявления.

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

  • let base = 3
  • let power = 10
  • var answer = 1
  • for _ in 1...power {
  • answer *= base
  • }
  • println("\(base) to the power of \(power) is \(answer)")
  • // prints "3 to the power of 10 is 59049"

Этот пример вычисляет значение одного числа к питанию другого (в этом случае, 3 к питанию 10). Это умножает начальное значение 1 (т.е. 3 к питанию 0) 3, десять раз, с помощью закрытого диапазона, запускающегося с 1 и концы с 10. Это вычисление не должно знать, что отдельный счетчик оценивает каждый раз через цикл — это просто должно выполнить цикл корректное число раз. Символ подчеркивания _ (используемый вместо переменной цикла), заставляет отдельные значения быть проигнорированными и не обеспечивает доступ к текущей стоимости во время каждой итерации цикла.

Используйте a for-in цикл с массивом для итерации по его элементам:

  • let names = ["Anna", "Alex", "Brian", "Jack"]
  • for name in names {
  • println("Hello, \(name)!")
  • }
  • // Hello, Anna!
  • // Hello, Alex!
  • // Hello, Brian!
  • // Hello, Jack!

Можно также выполнить итерации по словарю для доступа к его парам ключ/значение. Каждый элемент в словаре возвращается как a (key, value) кортеж, когда словарь выполнен с помощью итераций, и можно разложиться (key, value) элементы кортежа как явно названные константы для использования в организации for-in цикл. Здесь, ключи словаря анализируются в вызванную константу animalName, и значения словаря анализируются в вызванную константу legCount:

  • let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
  • for (animalName, legCount) in numberOfLegs {
  • println("\(animalName)s have \(legCount) legs")
  • }
  • // ants have 6 legs
  • // cats have 4 legs
  • // spiders have 8 legs

Элементы в a Dictionary может не обязательно быть выполнен с помощью итераций в том же порядке, как они были вставлены. Содержание a Dictionary по сути не упорядочиваются, и выполняющий итерации по ним не гарантирует порядка, в котором они будут получены. Для больше на массивах и словарях, посмотрите Типы Набора.)

В дополнение к массивам и словарям, можно также использовать for-in цикл для итерации по Character значения в строке:

  • for character in "Hello" {
  • println(character)
  • }
  • // H
  • // e
  • // l
  • // l
  • // o

Для

В дополнение к for-in циклы, Swift поддерживает традиционный C-стиль for циклы с условием и инкрементором:

  • for var index = 0; index < 3; ++index {
  • println("index is \(index)")
  • }
  • // index is 0
  • // index is 1
  • // index is 2

Вот общая форма этого формата цикла:

  • for initialization; condition; increment {
  •     statements
  • }

Точки с запятой разделяют три части определения цикла, как в C. Однако в отличие от C, Swift не нужны круглые скобки вокруг всей “инициализации; условие; постепенно увеличьте” блок.

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

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

  2. Выражение условия оценено. Если это оценивает к false, концы цикла и выполнение кода продолжаются после for закрывающая фигурная скобка цикла (}). Если выражение оценивает к true, выполнение кода продолжается путем выполнения операторов в фигурных скобках.

  3. После того, как все операторы выполняются, инкрементное выражение оценено. Это могло бы увеличить или уменьшить значение счетчика или установить одну из инициализированных переменных к новому значению на основе результата операторов. После того, как инкрементное выражение было оценено, выполнение возвращается к шагу 2, и выражение условия оценено снова.

Константы и переменные, объявленные в выражении инициализации (такой как var index = 0) только допустимы в рамках for сам цикл. Получать окончательное значение index после концов цикла необходимо объявить index прежде чем объем цикла начинается:

  • var index: Int
  • for index = 0; index < 3; ++index {
  • println("index is \(index)")
  • }
  • // index is 0
  • // index is 1
  • // index is 2
  • println("The loop statements were executed \(index) times")
  • // prints "The loop statements were executed 3 times"

Обратите внимание на то, что окончательное значение index после того, как этот цикл завершается, 3, нет 2. В прошлый раз инкрементный оператор ++index вызывается, это устанавливает index к 3, который вызывает index < 3 приравниваться к false, окончание цикла.

Циклы с условием продолжения

A while цикл выполняет ряд операторов, пока условие не становится false. Эти виды циклов лучше всего используются, когда число итераций не известно, прежде чем первая итерация начинается. Swift обеспечивает два вида while цикл:

  • while оценивает его условие в начале каждого, проходят через цикл.

  • do-while оценивает его условие в конце каждого, проходят через цикл.

В то время как

A while цикл запускается путем оценки единственного условия. Если условие true, ряд операторов повторяется, пока условие не становится false.

Вот общая форма a while цикл:

  • while condition {
  •     statements
  • }

Этот пример играет в простую игру Змей и Лестничных структур (также известный как Скаты и Лестничные структуры):

image: ../Art/snakesAndLadders_2x.png

Правила игры следующие:

  • Плата имеет 25 квадратов, и цель состоит в том, чтобы приземлиться на или вне квадратных 25.

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

  • Если Ваша очередь заканчивается у основания лестничной структуры, Вы повышаете ту лестничную структуру.

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

Игровая доска представлена массивом Int значения. Его размер основывается на вызванной константе finalSquare, который используется, чтобы инициализировать массив и также проверить на условие победы позже в примере. Плата инициализируется с 26 нулями Int значения, не 25 (один каждый в индексах 0 через 25 включительно):

  • let finalSquare = 25
  • var board = [Int](count: finalSquare + 1, repeatedValue: 0)

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

  • board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
  • board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08

Квадратные 3 содержат нижнюю часть лестничной структуры, перемещающей Вас до квадратных 11. Представлять это, board[03] равно +08, который эквивалентен целочисленному значению 8 (различие между 3 и 11). Унарное плюс оператор (+i) балансы с оператором унарный минус (-i), и числа ниже, чем 10 дополняются нулями так, чтобы выровнялись все определения платы. (Никакая стилистическая тонкая настройка не строго необходима, но они приводят к более опрятному коду.)

Стартовый квадрат проигрывателя является “квадратным нулем”, находящимся рядом с левым нижним углом платы. Первый бросок костей всегда углубляет проигрыватель к плате:

  • var square = 0
  • var diceRoll = 0
  • while square < finalSquare {
  • // roll the dice
  • if ++diceRoll == 7 { diceRoll = 1 }
  • // move by the rolled amount
  • square += diceRoll
  • if square < board.count {
  • // if we're still on the board, move up or down for a snake or a ladder
  • square += board[square]
  • }
  • }
  • println("Game over!")

Этот пример использует очень простой подход для игры в кости прокрутки. Вместо генератора случайных чисел, это запускается с a diceRoll значение 0. Каждый раз через while цикл, diceRoll постепенно увеличивается с префиксным инкрементным оператором (++i), и тогда проверяется, чтобы видеть, стало ли это слишком большим. Возвращаемое значение ++diceRoll равно значению diceRoll после того, как это постепенно увеличивается. Каждый раз, когда это возвращаемое значение равняется 7, бросок костей стал слишком большим, и сбрасывается к значению 1. Это дает последовательность diceRoll значения, который всегда является 1, 2, 3, 4, 5, 6, 1, 2 и т.д.

После кидания кости игровые движения передают diceRoll квадраты. Возможно, что бросок костей, возможно, переместил проигрыватель вне квадратных 25, когда игра закончена. Для разрешения с этим сценарием код проверяет это square меньше, чем board массив count свойство прежде, чем добавить значение, сохраненное в board[square] на ток square значение для повышения проигрывателя или вниз любых лестничных структур или змей.

Если бы эта проверка не была выполнена, board[square] мог бы попытаться получить доступ к значению вне границ board массив, который инициировал бы ошибку. Если square теперь равно 26, код попытался бы проверить значение board[26], который больше, чем размер массива.

Ток while выполнение цикла тогда заканчивается, и условие цикла проверяется, чтобы видеть, должен ли цикл быть выполнен снова. Если проигрыватель шел дальше или вне квадратного числа 25, условие цикла оценивает к false, и игровые концы.

A while цикл является надлежащим в этом случае, потому что длина игры не ясна в начале while цикл. Вместо этого цикл выполняется, пока определенное условие не удовлетворено.

Сделайте - В то время как

Другое изменение while цикл, известный как do-while цикл, выполняет единственную передачу через блок цикла сначала, прежде, чем рассмотреть условие цикла. Это тогда продолжает повторять цикл, пока условие не false.

Вот общая форма a do-while цикл:

  • do {
  •     statements
  • } while condition

Вот пример Змей и Лестничных структур снова, записан как a do-while цикл, а не a while цикл. Значения finalSquare, board, square, и diceRoll инициализируются точно таким же образом как с a while цикл:

  • let finalSquare = 25
  • var board = [Int](count: finalSquare + 1, repeatedValue: 0)
  • board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
  • board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
  • var square = 0
  • var diceRoll = 0

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

В начале игры проигрыватель находится на “квадратном нуле”. board[0] всегда равняется 0, и не имеет никакого эффекта:

  • do {
  • // move up or down for a snake or ladder
  • square += board[square]
  • // roll the dice
  • if ++diceRoll == 7 { diceRoll = 1 }
  • // move by the rolled amount
  • square += diceRoll
  • } while square < finalSquare
  • println("Game over!")

После проверок кода на змей и лестничные структуры, прокручивается игра в кости, и проигрыватель продвинут diceRoll квадраты. Текущее выполнение цикла тогда заканчивается.

Условие цикла (while square < finalSquare) совпадает с прежде, но на сей раз это не оценено до конца первого показа через цикл. Структура do-while цикл лучше подходит для этой игры, чем while цикл в предыдущем примере. В do-while цикл выше, square += board[square] всегда сразу выполняется после цикла while условие подтверждает это square находится все еще на плате. Это поведение устраняет необходимость граничной проверки массива, замеченной в более ранней версии игры.

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

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

Swift обеспечивает два способа добавить условные переходы к Вашему коду, известному как if оператор и switch оператор. Как правило, Вы используете if оператор для оценки простых условий только с несколькими возможными исходами. switch оператор лучше подходит для более сложных условий с многократными возможными перестановками и полезен в ситуациях, где сопоставление с образцом может помочь выбрать надлежащее ответвление кода для выполнения.

Если

В его самой простой форме, if оператор имеет сингл if условие. Это выполняет ряд операторов, только если то условие true:

  • var temperatureInFahrenheit = 30
  • if temperatureInFahrenheit <= 32 {
  • println("It's very cold. Consider wearing a scarf.")
  • }
  • // prints "It's very cold. Consider wearing a scarf."

Предыдущий пример проверяет, меньше чем или равна ли температура 32 градусам по Фаренгейту (точка замерзания воды). Если это, сообщение распечатано. Иначе, никакое сообщение не распечатано, и выполнение кода продолжается после if закрывающая фигурная скобка оператора.

if оператор может обеспечить альтернативный набор операторов, известных как выражение else, поскольку когда if условие false. Эти операторы обозначены else ключевое слово:

  • temperatureInFahrenheit = 40
  • if temperatureInFahrenheit <= 32 {
  • println("It's very cold. Consider wearing a scarf.")
  • } else {
  • println("It's not that cold. Wear a t-shirt.")
  • }
  • // prints "It's not that cold. Wear a t-shirt."

Одно из этих двух ответвлений всегда выполняется. Поскольку температура увеличилась до 40 градусы по Фаренгейту, больше не достаточно холодно, чтобы советовать носить шарф, и таким образом, else ответвление инициировано вместо этого.

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

  • temperatureInFahrenheit = 90
  • if temperatureInFahrenheit <= 32 {
  • println("It's very cold. Consider wearing a scarf.")
  • } else if temperatureInFahrenheit >= 86 {
  • println("It's really warm. Don't forget to wear sunscreen.")
  • } else {
  • println("It's not that cold. Wear a t-shirt.")
  • }
  • // prints "It's really warm. Don't forget to wear sunscreen."

Здесь, дополнительное if оператор добавляется для ответа на особенно теплые температуры. Финал else пункт остается и распечатывает ответ для любых температур, которые не являются ни слишком теплыми, ни слишком холодными.

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

  • temperatureInFahrenheit = 72
  • if temperatureInFahrenheit <= 32 {
  • println("It's very cold. Consider wearing a scarf.")
  • } else if temperatureInFahrenheit >= 86 {
  • println("It's really warm. Don't forget to wear sunscreen.")
  • }

В этом примере температура не является ни слишком холодной, ни слишком теплой для инициирования if или else if условия, и таким образом, не распечатано никакое сообщение.

Переключатель

A switch оператор рассматривает значение и сравнивает его с несколькими возможными образцами соответствия. Это тогда выполняет надлежащий блок кода, на основе первого образца, соответствующего успешно. A switch оператор обеспечивает альтернативу if оператор для ответа на многократные потенциальные состояния.

В его самой простой форме, a switch оператор сравнивает значение с одним или более значениями того же типа:

  • switch some value to consider {
  • case value 1:
  •     respond to value 1
  • case value 2,
  • value 3:
  •     respond to value 2 or 3
  • default:
  •     otherwise, do something else
  • }

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

Организация каждого switch случай является отдельным ответвлением выполнения кода, подобным образом к ответвлениям if оператор. switch оператор определяет, какое ответвление должно быть выбрано. Это известно как включение значения, которое рассматривают.

Каждый switch оператор должен быть исчерпывающим. Т.е. каждое возможное значение типа, который рассматривают, должно быть соответствующим одним из switch случаи. Если не является надлежащим обеспечить a switch случай для каждого возможного значения, можно определить всеобъемлющий случай по умолчанию для покрытия любых значений, не адресующихся явно. Этот всеобъемлющий случай обозначен ключевым словом default, и должен всегда появляться в последний раз.

Этот пример использует a switch оператор для рассмотрения единственного символа нижнего регистра вызванным someCharacter:

  • let someCharacter: Character = "e"
  • switch someCharacter {
  • case "a", "e", "i", "o", "u":
  • println("\(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":
  • println("\(someCharacter) is a consonant")
  • default:
  • println("\(someCharacter) is not a vowel or a consonant")
  • }
  • // prints "e is a vowel"

switch первый случай оператора соответствует все пять строчных гласных на английском языке. Точно так же его второй случай соответствует все строчные английские согласные.

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

Никакой неявный Fallthrough

В отличие от switch операторы в C и Objective C, switch операторы в Swift не проваливаются нижняя часть каждого случая и в следующий по умолчанию. Вместо этого все switch оператор заканчивает свое выполнение как только первое соответствие switch случай завершается, не требуя явного break оператор. Это делает switch оператор, более безопасный и проще использовать, чем в C, и, избегает выполнять больше чем один switch случай по ошибке.

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

  • let anotherCharacter: Character = "a"
  • switch anotherCharacter {
  • case "a":
  • case "A":
  • println("The letter A")
  • default:
  • println("Not the letter A")
  • }
  • // this will report a compile-time error

В отличие от a switch оператор в C, этом switch оператор не соответствует обоим "a" и "A". Скорее это сообщает об ошибке времени компиляции это case "a": не содержит исполнимых операторов. Этот подход избегает случайного fallthrough от одного случая до другого и делает для более безопасного кода, который более ясен в его намерении.

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

  • switch some value to consider {
  • case value 1,
  • value 2:
  •     statements
  • }

Соответствие интервала

Значения в switch случаи могут быть проверены на их включение в интервал. Этот пример использует интервалы числа для обеспечения счета естественного языка для чисел любого размера:

  • let count = 3_000_000_000_000
  • let countedThings = "stars in the Milky Way"
  • var naturalCount: String
  • switch count {
  • case 0:
  • naturalCount = "no"
  • case 1...3:
  • naturalCount = "a few"
  • case 4...9:
  • naturalCount = "several"
  • case 10...99:
  • naturalCount = "tens of"
  • case 100...999:
  • naturalCount = "hundreds of"
  • case 1000...999_999:
  • naturalCount = "thousands of"
  • default:
  • naturalCount = "millions and millions of"
  • }
  • println("There are \(naturalCount) \(countedThings).")
  • // prints "There are millions and millions of stars in the Milky Way."

Кортежи

Можно использовать кортежи для тестирования многократных значений в том же switch оператор. Каждый элемент кортежа может быть протестирован против различного значения или интервала значений. Также используйте подчеркивание (_) идентификатор для соответствия любого возможного значения.

Пример ниже взятий (x, y) точка, выраженная как простой кортеж типа (Int, Int), и категоризирует его на графике, следующем примеру:

  • let somePoint = (1, 1)
  • switch somePoint {
  • case (0, 0):
  • println("(0, 0) is at the origin")
  • case (_, 0):
  • println("(\(somePoint.0), 0) is on the x-axis")
  • case (0, _):
  • println("(0, \(somePoint.1)) is on the y-axis")
  • case (-2...2, -2...2):
  • println("(\(somePoint.0), \(somePoint.1)) is inside the box")
  • default:
  • println("(\(somePoint.0), \(somePoint.1)) is outside of the box")
  • }
  • // prints "(1, 1) is inside the box"
image: ../Art/coordinateGraphSimple_2x.png

switch оператор определяет, ли точка в источнике (0, 0); на красной оси X; на оранжевой оси y; в синем 4 4 поле центрировалось на источнике; или за пределами поля.

В отличие от C, Swift позволяет многократный switch случаи для рассмотрения того же значения или значений. Фактически, точка (0, 0) могла соответствовать все четыре из случаев в этом примере. Однако, если многократные соответствия возможны, первый случай соответствия всегда используется. Точка (0, 0) соответствовала бы case (0, 0) во-первых, и таким образом, все другие регистры соответствия игнорировались бы.

Привязка значения

A switch случай может связать значение или оценивает, это соответствует к временным константам или переменным для использования в организации случая. Это известно как привязка значения, потому что значения «связываются» с временными константами или переменными в организации случая.

Пример ниже взятий (x, y) точка, выраженная как кортеж типа (Int, Int) и категоризирует его на графике, следующем:

  • let anotherPoint = (2, 0)
  • switch anotherPoint {
  • case (let x, 0):
  • println("on the x-axis with an x value of \(x)")
  • case (0, let y):
  • println("on the y-axis with a y value of \(y)")
  • case let (x, y):
  • println("somewhere else at (\(x), \(y))")
  • }
  • // prints "on the x-axis with an x value of 2"
image: ../Art/coordinateGraphMedium_2x.png

switch оператор определяет, находится ли точка на красной оси X, на оранжевой оси y, или в другом месте, ни на какой оси.

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

Как только временные константы объявляются, они могут использоваться в блоке кода случая. Здесь, они используются в качестве сокращения для печати значений с println функция.

Обратите внимание на то, что это switch оператор не имеет a default случай. Заключительный случай, case let (x, y), объявляет кортеж двух констант заполнителя, которые могут соответствовать любое значение. В результате это соответствует все возможные остающиеся значения и a default случай не необходим для создания switch исчерпывающий оператор.

В примере выше, x и y объявляются как константы с let ключевое слово, потому что нет никакой потребности изменить их значения в организации случая. Однако они, возможно, были объявлены как переменные вместо этого, с var ключевое слово. Если бы это было сделано, то временная переменная была бы создана и инициализирована с надлежащим значением. Любые изменения в той переменной только имели бы эффект в организации случая.

Где

A switch случай может использовать a where пункт для проверки на дополнительные условия.

Пример ниже категоризирует (x, y) точка на следующем графике:

  • let yetAnotherPoint = (1, -1)
  • switch yetAnotherPoint {
  • case let (x, y) where x == y:
  • println("(\(x), \(y)) is on the line x == y")
  • case let (x, y) where x == -y:
  • println("(\(x), \(y)) is on the line x == -y")
  • case let (x, y):
  • println("(\(x), \(y)) is just some arbitrary point")
  • }
  • // prints "(1, -1) is on the line x == -y"
image: ../Art/coordinateGraphComplex_2x.png

switch оператор определяет, находится ли точка на зеленой диагональной строке где x == y, на фиолетовой диагональной строке, где x == -y, или ни один.

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

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

Проверьте утверждения передачи

Операторы передачи управления изменяют порядок, в котором Ваш код выполняется путем передачи управления от одной части кода другому. Swift имеет четыре, проверяют утверждения передачи:

  • continue

  • break

  • fallthrough

  • return

continue, break, и fallthrough операторы описаны ниже. return оператор описан в Функциях.

Продолжать

continue оператор говорит циклу останавливать то, что он делает, и запустите снова в начале следующей итерации через цикл. Это говорит, что “Я сделан с текущей итерацией цикла”, не оставляя цикл в целом.

Следующий пример удаляет все гласные и пробелы от строчной строки для создания загадочной фразы проблемы:

  • let puzzleInput = "great minds think alike"
  • var puzzleOutput = ""
  • for character in puzzleInput {
  • switch character {
  • case "a", "e", "i", "o", "u", " ":
  • continue
  • default:
  • puzzleOutput.append(character)
  • }
  • }
  • println(puzzleOutput)
  • // prints "grtmndsthnklk"

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

Повреждение

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

Прервите инструкцию циклов

Когда используется в инструкции циклов, break сразу заканчивает выполнение цикла и передает управление первой строке кода после закрывающей фигурной скобки цикла (}). Никакой дальнейший код от текущей итерации цикла не выполняется, и никакие дальнейшие итерации цикла не запускаются.

Прервите оператор переключения

Когда используется внутри a switch оператор, break причины switch оператор, чтобы сразу закончить его выполнение и передать управление первой строке кода после switch закрывающая фигурная скобка оператора (}).

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

Следующий пример включает a Character оцените и определяет, представляет ли это символ числа на одном из четырех языков. Многократные значения покрыты синглом switch случай для краткости:

  • let numberSymbol: Character = "三" // Simplified Chinese for the number 3
  • var possibleIntegerValue: Int?
  • switch numberSymbol {
  • case "1", "١", "一", "๑":
  • possibleIntegerValue = 1
  • case "2", "٢", "二", "๒":
  • possibleIntegerValue = 2
  • case "3", "٣", "三", "๓":
  • possibleIntegerValue = 3
  • case "4", "٤", "四", "๔":
  • possibleIntegerValue = 4
  • default:
  • break
  • }
  • if let integerValue = possibleIntegerValue {
  • println("The integer value of \(numberSymbol) is \(integerValue).")
  • } else {
  • println("An integer value could not be found for \(numberSymbol).")
  • }
  • // prints "The integer value of 三 is 3."

Этот пример проверки numberSymbol определить, является ли это латинским, арабским, китайским или тайским символом для чисел 1 к 4. Если соответствие найдено, один из switch случаи оператора устанавливают дополнительное Int? переменную вызывают possibleIntegerValue к надлежащему целочисленному значению.

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

Это не практично для перечисления каждого возможного Character значение в примере выше, таким образом, a default случай обеспечивает вместилище для любых символов, которые не являются соответствующими. Это default случай не должен выполнять действие, и таким образом, это записано с синглом break оператор как его организация. Как только default случай является соответствующим, break оператор заканчивается switch выполнение оператора и выполнение кода продолжаются от if let оператор.

Fallthrough

Операторы переключения в Swift не проваливаются нижняя часть каждого случая и в следующий. Вместо этого оператор целостного коммутатора завершает свое выполнение, как только завершается первый случай соответствия. В отличие от этого, C требует, чтобы Вы вставили явное break оператор в конце каждого switch случай для предотвращения fallthrough. При предотвращении значения по умолчанию fallthrough означает тот Swift switch операторы намного более кратки и предсказуемы, чем их дубликаты в C, и таким образом они избегают выполняться многократный switch случаи по ошибке.

При реальной необходимости в C-стиле fallthrough поведение можно выбрать в к этому поведению в зависимости от конкретного случая с fallthrough ключевое слово. Пример ниже использования fallthrough создать текстовое описание числа:

  • let integerToDescribe = 5
  • var description = "The number \(integerToDescribe) is"
  • switch integerToDescribe {
  • case 2, 3, 5, 7, 11, 13, 17, 19:
  • description += " a prime number, and also"
  • fallthrough
  • default:
  • description += " an integer."
  • }
  • println(description)
  • // prints "The number 5 is a prime number, and also an integer."

Этот пример объявляет новое String переменную вызывают description и присваивает его начальное значение. Функция тогда рассматривает значение integerToDescribe использование a switch оператор. Если значение integerToDescribe одно из простых чисел в списке, функция добавляет текст до конца description, отметить, что число является главным. Это тогда использует fallthrough ключевое слово для “падения в” default случай также. default случай добавляет некоторый дополнительный текст до конца описания, и switch оператор завершен.

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

После switch оператор закончил выполняться, описание числа распечатано с помощью println функция. В этом примере, числе 5 правильно идентифицируется как простое число.

Помеченные операторы

Можно вложить циклы и switch операторы в других циклах и switch операторы в Swift для создания сложных структур потока управления. Однако циклы и switch операторы могут оба использовать break оператор для окончания их выполнения преждевременно. Поэтому иногда полезно быть явным о который цикл или switch оператор Вы хотите a break оператор для завершения. Точно так же, если у Вас есть многократные вложенные циклы, может быть полезно быть явным, о котором циклично выполняются continue оператор должен влиять.

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

Помеченный оператор обозначен путем размещения метки на той же строке как introducer ключевое слово оператора, сопровождаемое двоеточием. Вот пример этого синтаксиса для a while цикл, несмотря на то, что принцип является тем же для всех циклов и switch операторы:

  • label name: while condition {
  •     statements
  • }

Следующий пример использует break и continue операторы с маркированным while цикл для адаптированной версии игры Змей и Лестничных структур, которую Вы видели ранее в этой главе. На сей раз вокруг, игра имеет дополнительное правило:

  • Для завоевания необходимо приземлиться точно на квадратные 25.

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

Игровая доска совпадает с прежде:

image: ../Art/snakesAndLadders_2x.png

Значения finalSquare, board, square, и diceRoll инициализируются таким же образом как прежде:

  • let finalSquare = 25
  • var board = [Int](count: finalSquare + 1, repeatedValue: 0)
  • board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
  • board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
  • var square = 0
  • var diceRoll = 0

Эта версия игры использует a while цикл и a switch оператор для реализации логики игры. while циклу вызвали метку оператора gameLoop, указать, что это - основной игровой цикл для игры Змей и Лестничных структур.

while условие цикла while square != finalSquare, отразить, что необходимо приземлиться точно на квадратные 25:

  • gameLoop: while square != finalSquare {
  • if ++diceRoll == 7 { diceRoll = 1 }
  • switch square + diceRoll {
  • case finalSquare:
  • // diceRoll will move us to the final square, so the game is over
  • break gameLoop
  • case let newSquare where newSquare > finalSquare:
  • // diceRoll will move us beyond the final square, so roll again
  • continue gameLoop
  • default:
  • // this is a valid move, so find out its effect
  • square += diceRoll
  • square += board[square]
  • }
  • }
  • println("Game over!")

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

  • Если бросок костей перейдет проигрыватель на заключительный квадрат, игра закончена. break gameLoop оператор передает управление первой строке кода за пределами while цикл, заканчивающий игру.

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

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