continue
, break
и fallthrough
описаны в данной главе.
continue
приказывает циклу остановить своё выполнение и начать заново с новой итерации. Он означает дословно следующее: "Я завершил текущий шаг цикла." без выхода из цикла в целом.
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput.characters {
if charactersToRemove.contains(character) {
continue
} else {
puzzleOutput.append(character)
}
}
print(puzzleOutput)
// Выведет "grtmndsthnklk"
Код вызывает ключевое слово continue
, когда происходит совпадение с гласной буквой или пробелом, вызывая немедленное прекращение текущей итерации и переход непосредственно в начало следующей итерации.
break
заканчивает исполнение всей инструкции немедленно. Инструкция break
может быть использована внутри switch
или цикла, когда Вы хотите терминировать их выполнение раньше, чем это должно было случиться.
break
заканчивает выполнение цикла немедленно и передаёт управление в код сразу после закрывающей фигурной скобки (}). Никакой дальнейший код из текущей итерации не будет выполнен, а никакие будущие итерации цикла не будут выполнены.
switch
, break
вызывает завершение выполнения инструкции switch
немедленно и передают управление в код сразу после закрывающей фигурной скобки инструкции switch
(}).
switch
. Так как инструкция switch
в Swift исчерпывающа и не допускает пустых кейсов, то иногда бывает необходимым принудительно выделить и проигнорировать кейс, дабы сделать Ваши намерения явными. Вы делаете это с помощью написания инструкции break
в качестве всего тела кейса, который Вы хотите проигнорировать. Когда этот кейс выбран инструкцией switch
, инструкция break
внутри кейса прекращает выполнение всей инструкции switch
немедленно.
switch
, содержащий лишь комментарий, будут помечен в качестве ошибки времени выполнения. Комментарии не являются инструкциями и не могут вызвать игнорирование кейса switch
. Всегда используйте инструкцию break
, чтобы проигнорировать кейс switch
.
Character
и определяет, когда он представляет числовой символ в одном из четырёх языков. Для краткости различные значения покрываются одним кейсом switch
.
let numberSymbol: Character = "三" // Цифра 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 {
print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
print("An integer value could not be found for \(numberSymbol).")
}
// Выведет "The integer value of 三 is 3."
В этом примере проверяется numberSymbol
для определения того, является ли он Латинским, Арабским, Китайским или Тайским символом для чисел от 1 до 4. Если совпадение найдено, то один из кейсов инструкции switch
устанавливает опциональной переменной типа Int?
с названием possibleIntegerValue
подходящее целое значение.
switch
завершает своё выполнение, в примере используется опциональная привязка для определения того, найдено ли значение. possibleIntegerValue
имеет неявно заданное изначальное значение nil
ввиду опциональности типа, так что опциональное связывание будет имеет успех, только если possibleIntegerValue
получит какое-то значение в одном из первых четырёх кейсов инструкции switch
.
Character
в примере выше, то кейс default
обрабатывает все символы, которые не имеют совпадения с другими кейсами. Кейсу default
нет необходимости выполнять какие-либо действия, так что он записывается в качестве единственной инструкции break
в качестве тела. Как только кейс default
получен, инструкция break
заканчивает выполнение всей инструкции switch
, а выполнение кода продолжится с инструкции if let
.
switch
не проваливается внизу каждого кейса и в следующий кейс. Это значит, что вся инструкция switch
завершает своё выполнение, как только первый подходящий кейс буде завершён. Напротив, С требует от Вас явной вставки инструкции break
в конце каждого кейса switch
для препятствования такому поведению. Избежание провала по-умолчанию означает, что инструкции switch
в Swift более краткие и предсзкауемые, чем их аналоги в C, а также они позволяют избегать выполнения нескольких кейсов по ошибке.
fallthrough
. Пример демонстрирует использование falltrough
для создания текстового описания числа:
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."
}
print(description)
// Выведет "The number 5 is a prime number, and also an integer."
В этом примере объявляется новая переменная типа String
под названием description
, и ей присваивается изначальное значение. Затем функция определяет значение integerToDescribe
с использованием инструкции switch
. Если значение integerToDescribe
является одним из простых чисел в списке, то функция прибавляет текст в конец description
, чтобы отметить, что число простое. Здесь используется ключевое слово fallthrough
для "падения в" кейс default
. Кейс default
добавляет некоторый дополнительный текст в конец описания, и выполнение инструкции switch
завершается.
integerToDescribe
оказывается в списке известных простых чисел, то оно не совпадёт с первым кейсом switch
в принципе. Так как не определено никаких других специальных кейсов, то integerToDescribe
попадёт в кейс default
.
switch
завершила своё выполнение, то описание числа печатается с использованием функции print(_:separator:terminator:)
. В этом примере число 5 корректно идентифицируется в качестве простого числа.
fallthrough
не проверяет условия кейса switch
, а просто передаёт управление вниз. Ключевое слово fallthrough
просто переводит выполнение кода прямо внутрь инструкций следующего кейса (или кейса default
), что является стандартным поведением инструкции switch
в C.
break
для принудительного завершения их выполнения. Поэтому иногда бывает полезным явно знать, какой цикл или условная инструкция будет терминирована инструкцией break
. Аналогично, если Вы имеете несколько вложенных циклов, то может быть полезным явно знать, на какой цикл инструкция continue
окажет эффект.
break
для завершения выполнения помеченной инструкции. С инструкцией цикла Вы можете использовать инструкцию пометки с инструкциями break
или continue
для завершения выполнения или продолжения выполнения помеченных инструкций.
while
, хотя этот принцип и одинаков для всех циклов и инструкций switch
.
break
и continue
с маркированным циклом 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
gameLoop: while square != finalSquare {
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
switch square + diceRoll {
case finalSquare:
// diceRoll передвинет нас на финальную клетку, так что игра окончена
break gameLoop
case let newSquare where newSquare > finalSquare:
// diceRoll передвинет нас за пределы игрового поля, так что бросим ещё раз
continue gameLoop
default:
// это корректный ход, так что узнаем его эффект
square += diceRoll
square += board[square]
}
}
print("Game over!")
Эта версия игры использует цикл while
и инструкцию switch
для реализации логики игры. Цикл while
имеет инструкцию маркера с названием gameLoop
для индикации того, что это главный цикл игры.
while
имеет вид while square != finalSquare
для отражения того, что Вы должны оказаться ровно на квадрате 25.
switch
для определения результата перемещения и определения, когда разрешено движение:
break gameLoop
передаёт управление первой строчке кода за пределами цикла while
, который завершает игру.
continue gameLoop
завершает текущую итерацию цикла while
и начинает новую.
diceRoll
, и логика игры производит проверку на наличие змей и лестниц. Затем цикл завершается, а управление возвращается условию цикла while
для определения того, нужен ли ещё один ход.
break
выше не использовала бы маркер gameLoop
, то она бы вышла за пределы инструкции switch
, а не while
. Использование маркера gameLoop
делает более понятным, какая инструкция управления должна быть терминирована.
gameLoop
при вызове continue gameLoop
для перехода на следующую итерацию цикла. В игре есть всего один цикл, а значит не существует и неопределенности, на какой цикл повлияет инструкция continue
. Однако, нет ничего плохого в использовании маркера gameLoop
с инструкцией continue
. Делая так, мы делаем нашу логику игры понятнее для чтения и понимания.