Документация

Инструкции

В Swift существуют три вида инструкций: простые инструкции, инструкции управления компилятором, а также инструкции управления потоком. Простые инструкции являются наиболее распространенными и состоят либо из выражения, либо из объявления. Инструкции управления компилятором позволяют программе изменять аспекты поведения компилятора, включают в себя конфигурацию сборки и инструкции управления строкой.

Инструкции управления потоком используются для управления потоком выполнения программы. Есть несколько типов инструкций управления потоками в Swift, в том числе инструкции цикла, инструкции ветвления, а также инструкции передачи управления. Инструкции цикла позволяют блоку кода выполняться несколько раз, инструкции ветвления позволяют определенному блоку кода выполняться только при выполнении определенных условий, а также инструкции передачи управления обеспечивают возможность изменять порядок, в котором будет выполняться код. Кроме того, Swift предоставляет инструкцию do для представления области для обработки ошибок, а также инструкцию defer для запуска очистки непосредственно перед как мы покинем эту область видимости.

Точка с запятой (;) может использоваться по желанию после любой инструкции и используется для разделения нескольких инструкций, если они находятся в одной и той же строке.

Грамматика инструкций

statement → expression­opt­ statement → declaration­opt­ statement → loop-statement­opt­ statement → branch-statement­opt­ statement → labeled-statement­opt­ statement → control-transfer-statement­opt­ statement → defer-statement­opt­ statement → do-statement­opt­ statement → compiler-control-statement­ statements → statement­ statements­ opt­

Инструкции цикла

Инструкции цикла позволяют блоку кода выполняться несколько раз, в зависимости от условий, указанных в цикле. В Swift есть три инструкции цикла: инструкция for-in, инструкция while, и инструкция repeat-while.

Управление потоком в инструкции цикла может быть изменено инструкцией break и continue и более подробно обсуждается в "Инструкция Break" и "Инструкция Continue" ниже.

Грамматика инструкции цикла

loop-statement → for-in-statement­
loop-statement → while-statement­
loop-statement → repeat-while-statement­

Инструкция for-in

Инструкция for-in позволяет блоку кода выполняться один раз для каждого элемента в коллекции (или любого типа), соответствующего протоколу Sequence.

Выглядит следующим образом:

for item in collection{
выражения
}

Метод makeIterator() вызывается на выражение коллекции для получения значения итератора типа - это тип, который соответствует протоколу IteratorProtocol. Программа начинает выполнение цикла, вызывая метод next() в потоке. Если возвращенное значение не nil, оно вписывается под шаблон элемента, программа выполняет инструкции, а затем переносит выполнение на начало цикла. В противном случае программа не выполняет инструкции присваивания или исполнения и заканчивает выполнение иструкции for-in.

Грамматика инструкции for-in

for-in-statement → for­ case­opt ­pattern ­in ­expression ­where-clause­ opt ­code-block­

Инструкция while

Инструкция while позволяет блоку кода выполняться несколько раз, до тех пор, пока условие остается верным.

Инструкция while выглядит следующим образом:

while условие{
выражения
}

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

  1. Происходит оценка состояния. Если true, то выполнение переходит к шагу 2. Если false, то программа завершается выполнением инструкции while.
  2. Программа выполняет инструкции, и выполнение программы возвращается к шагу 1.

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

Значение условия должно иметь тип, соответствующий протоколу Boolean. Условие может быть также объявлением опциональной привязки, как это описано Привязка опционалов.

Грамматика инструкции while

while-statement → while­ condition-clause­ code-block­ condition-list → condition­ | condition­condition-list­ condition → expression | availability-condition | case-condition­ | optional-binding-condition­ case-condition → case­ pattern­initializer optional-binding-condition → let pattern initializer | var pattern initializer 

Инструкция repeat-while

Инструкция repeat-while позволяет блоку кода выполняться один или несколько раз, до тех пор, пока условие остается верным.

Выглядит следующим образом:

repeat {
выражения
} while условие

Инструкция repeat-while выполняется следующим образом:

  1. Программа выполняет инструкции, и выполнение переходит к шагу 2.
  2. Происходит оценка условия.

Если true, выполнение возвращается к шагу 1. Если false, то программа завершает выполнение инструкции repeat-while.

Поскольку значение условия вычисляется после того, как выполняются инструкции, инструкции в инструкции repeat-while выполняются по крайней мере один раз.

Значение условия должно иметь тип, соответствующий протоколу Boolean. Условие может быть также опциональным связывающим объявлением, см. Привязка опционалов.

Грамматика repeat-while инструкции

repeat-while-statement repeat ­code-block while­ expression­

Инструкции ветвления

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

Управление потоком в инструкции if или инструкции switch может быть изменено инструкцией break и рассматривается в разделе Инструкция break ниже.

Грамматика инструкций ветвления

branch-statement → if-statement­
branch-statement → guard-statement­
branch-statement → switch-statement­

Инструкция if

Инструкция if используется для выполнения кода, на основе оценки одного или нескольких условий.

Существуют две основные формы инструкции if. Для каждой из них требуются открывающиеся и закрывающиеся фигурные скобки.

if условие {
выражения
}

Второй вариант формы инструкции if дает дополнительное условие else (вводимое ключевым словом else) и используется для выполнения одной части кода, когда условие true, и другой части кода, когда это же условие false. Когда есть только одно условие else, инструкция if выглядит следующим образом:

if условие {
выражения для исполнения, если условие true
} else {
выражения для исполнения, если условие false
}

Условие else инструкции if может содержать другую инструкцию if для проверки более, чем одного условия. Инструкция if, соединенная друг с другом таким образом, будет выглядеть вот так:

if условие 1 {
выражения для исполнения, если условие 1 равно true
} else if условие 2 {
выражения для исполнения, если условие 2 равно true
} else {
выражения для исполнения, если условие 1 и 2 равны false
}

Значение любого условия в инструкции if должно иметь тип, соответствующий протоколу Boolean. Условие может быть также объявлением опциональной привязки, см. Привязка опционалов.

Грамматика инструкции if

if-statement → if­ condition-clause­   code-block  ­else-clause ­opt­ else-clause → else­ code-block­  |  else ­if-statement­

Инструкция guard

Инструкция guard используется для перевода контроля программы из области видимости, если одно или несколько условий не выполняются.

Выглядит следующим образом:

guard условие else {
выражения для исполнения, если условие false
}

Значение любого состояния в инструкции guard должно иметь тип, соответствующий протоколу Boolean. Условие может быть также объявлением опциональной привязки, см. Привязка опционалов.

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

Требуется условие else инструкции guard, и оно должно либо вызывать функцию, отмеченную атрибутом noreturn или передать программное управление за пределы области видимости инструкции guard, используя одну из следующих инструкций:

  • return 
  • break
  • continue
  • throw

Инструкции передачи управления рассматриваются ниже в разделе "Операторы передачи управления". Для получения дополнительной информации о функциях с атрибутом noreturn, см. Функции, не возвращающие значения.

Грамматика инструкции guard

guard-statement → guard­ condition-clause­ else ­code-block­

Инструкция switch

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

Инструкция switch имеет следующий вид:

switch контрольное выражение {
case шаблон 1
выражения
case шаблон 2 where условие:
выражения
case шаблон 3 where условие:
case шаблон 4 where условие:
выражения
default:
выражения
}

Контрольное выражение инструкции switch вычисляются и сравниваются с шаблонами, указанными в каждом конкретном случае (кейсе). Если найдено совпадение, программа выполняет инструкции, перечисленные в теле этого кейса. Тело каждого кейса не может быть пустым. В результате, вы должны включить, по меньшей мере, одну инструкцию, идущую после знака двоеточия (:) для каждого отдельного кейса. Используйте только одну инструкцию break, если не собираетесь выполнять какой-либо код в теле совпавшего кейса.

Значения выражения вашего кода могут очень гибко разветвляться. Например, в дополнение к значениям скалярных типов, таким как Int и Character, ваш код может разветвляться на значения любого типа, в том числе числа с плавающей точкой, строки, кортежи, экземпляры пользовательских классов и опционалы. Значение контрольного выражения может даже быть сопоставлено со значением кейса в перечислении и проверяться для включения в указанный диапазон значений. Подробнее о различных типах этих значений инструкции switch вы можете прочитать в Управление потоком в разделе Switch .

Кейс switch может опционально содержать условие where после каждого шаблона. Условие where вводится с помощью ключевого слова where, за которым следует выражение, и используется для введения дополнительного условия до шаблона, в случае если он соответствует выражению управления. Если есть условие where, инструкции внутри соответствующего кейса выполняются только в том случае, если значение контрольного выражения совпадает с одним из шаблонов кейса и выражения, в котором условие оценивается как true. Например, в приведенном ниже примере, контрольное выражение будет соответствовать кейсу, только если оно будет кортежем, содержащем два элемента одного и того же значения, такие как (1, 1).

case let (x, y) where x == y:

Как показано в примере выше, шаблоны в кейсе также могут связать константы, используя ключевое слово let (они также могут связывать переменные с помощью ключевого слова var). На эти константы (или переменные) затем могут ссылаться в соответствующем условии where и в остальной части кода в области данного кейса. Тем не менее, если кейс содержит несколько шаблонов, соответствующих выражению управления, то ни один из этих шаблонов не может содержать константу или привязки переменных.
Инструкция switch может также включать в себя дефолтный кейс, вводимый ключевым словом default. Код в дефолтном кейсе выполняется только, если другие кейсы не совпадают с контрольным выражением. Инструкция switch может включать в себя только один дефолтный кейс, и располагаться он должен в конце инструкции switch.

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

Инструкция Switch должна быть исчерпывающей

В Swift каждое возможное значение типа контрольного выражения должно соответствовать значению, по меньшей мере, одного шаблона кейса. Когда это просто не представляется возможным (например, когда тип контрольного выражения является Int), вы можете включить дефолтный кейс (default), чтобы удовлетворить требование.

Переключение между будущими кейсами перечисления

Незамороженное перечисление - специальный вид перечисления, которое может получать новые кейсы в будущем, даже если вы скомпилировали приложение и отправили его. Переключение между кейсами незамороженного перечисления требует особого внимания. Когда авторы библиотеки маркируют перечисления как незамороженное, то они резервируют право добавлять новые кейсы перечисления в коде, который работает с этим перечислением. Примечательно, что любой код, который работает с этими будущими кейсами должен обрабатывать эти кейсы без повторной компиляции. Swift перекрывает фреймворки Apple, код на C и Objective-C стандартной библиотеки, чтобы была возможность создавать незамороженные перечисления. Перечисления, определяемые в Swift, не могут быть  незамороженными.

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

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

let representation: Mirror.AncestorRepresentation = .generated
switch representation {
case .customized:
    print("Use the nearest ancestor’s implementation.")
case .generated:
    print("Generate a default mirror for all ancestor classes.")
case .suppressed:
    print("Suppress the representation of all ancestor classes.")
@unknown default:
    print("Use a representation that was unknown when this code was compiled.")
}
// Выведет "Generate a default mirror for all ancestor classes."

Выполнение неявно не “проваливается” через кейсы

После того, как код в совпавшем кейсе завершит выполнение, программа выходит из инструкции switch. Выполнение программы не продолжается и не «проваливается» к следующему кейсу или дефолтному кейсу. Тем не менее, если вы хотите продолжить выполнение одного кейса за другим, явно включите инструкцию fallthrough, который просто состоит из ключевого слова fallthrough, в кейсе, с которого вы хотите продолжить выполнение. Для получения дополнительной информации об инструкции fallthrough см. раздел "Инструкция Fallthrough" ниже.

Грамматика инструкции switch

switch-statement → switch­ expression­switch-cases­opt­ switch-cases → switch-case­ switch-cases­ opt­ switch-case → case-label­ statements­  |  default-label­ statements­ case-label → case­ case-item-list­ case-item-list → pattern­ where-clause­opt­  |  pattern ­where-clause­opt­case-item-list­ default-label → default­ where-clause → where­ where-expression­ where-expression → expression­

Маркированная инструкция

Вы можете добавить префикс ярлыка инструкции к инструкции цикла, к инструкции if или к инструкции switch, который состоит из имени маркера, который следует непосредственно за двоеточием (:). Используйте маркеры инструкции с инструкциими break и continue, чтобы явно заявить о том, как вы хотите изменить управление потоком в инструкции цикла или инструкции switch, как это описано в "Инструкции Break" и "Инструкции Continue" .

Область маркированной инструкции - это вся инструкция, за которой следует маркер инструкции. Вы можете вкладывать друг в друга маркированные инструкции, но имя каждой инструкции должно быть уникальным.

О том как использовать маркеры инструкции см. Маркированные инструкции.

Грамматика маркированных инструкций

labeled-statement → statement-label­ loop-statement­ 
labeled-statement →statement-label ­if-statement­
labeled-statement →statement-label­ switch-statement­
labeled-statement →statement-label do-statement

statement-label → label-name­ label-name → identifier­

Операторы передачи управления

Операторы передачи управления могут изменять порядок выполнения кода в вашей программе, передавая управление программой от одного куска кода к другому. В Swift есть пять инструкций передачи управления: инструкция break, инструкция continue, инструкция fallthrough, инструкция return и инструкция throw.

Грамматика инструкции передачи управления

control-transfer-statement → break-statement­
control-transfer-statement → continue-statement­
control-transfer-statement → fallthrough-statement­
control-transfer-statement → return-statement­
control-transfer-statement → throw-statement­

Инструкция break

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

break
break имя ярлыка

Когда за инструкцией break следует имя маркера инструкции, он заканчивает выполнение программы цикла, инструкции if или инструкции switch, названного этим маркером.

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

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

Подробнее см. "Оператор Break" и Маркированные инструкции в Управление потоком.

Грамматика инструкции Break

break-statement → break ­label-name­ opt­

Инструкция continue

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

continue
continue имя ярлыка

Когда за оператором continue следует имя маркера инструкции, оно заканчивает выполнение программы текущей итерации инструкции цикла, названного этим маркером.

Когда за оператором continue не следует имя маркера инструкции, оно заканчивает выполнение программы текущей итерации самого внутреннего инструкции цикла, в котором находится.

В обоих случаях, управление программой затем переносится на состояние внутренней инструкции цикла.

В инструкции for инкрементирующее выражение по-прежнему оценивается после того, как будет выполнена инструкция continue, так как инкрементирующее выражение вычисляется после выполнения тела цикла.

Подробнее см.  Оператор Continue и Маркированные инструкции в Управление потоком.

Грамматика инструкции Continue

continue-statement → continue­ label-name­ opt­

Инструкция fallthrough

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

Инструкция fallthrough может появиться в любом месте внутри инструкции switch, а не только в качестве последней инструкции блока кейса, но она не может быть использован в финальном блоке кейса. Также она не может передавать управление блоку кейса, шаблон которого содержит значение связывающих шаблонов.

Подробнее см.  "Операторы передачи управления" в Управление потоком.

Грамматика инструкции fallthrough

fallthrough-statement → fallthrough­

Инструкция return

Инструкция return встречается в теле функции или определения метода и благодаря ему выполнение программы возвращается к вызову функции или метода. Выполнение программы продолжается сразу после вызова функции или метода.

Инструкция return может состоять только из ключевого слова return, или из ключевого слова return, за которым будет следовать выражение, как показано ниже:

return
return выражение

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

Заметка

Как описано в разделе Проваливающиеся инициализаторы, специальная форма инструкции return (return nil) может быть использована в failable инициализаторе для того, чтобы информировать о неудачной инициализации.

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

Грамматика инструкции return

return-statement → return­ expression­ opt­

Инструкция throw

Инструкция throw встречается в теле генерирующей ошибку функции или метода, или в теле выражения замыкания, тип которого отмечен ключевым словом throws.

Благодаря инструкции throw программа завершает выполнение текущей области и начинает распространение ошибок в области видимости. Сгенерированная ошибка продолжает распространяться, пока она не будет обработана условием catch инструкции do.

Инструкция throw состоит из ключевого слова throw, за которым следует выражение, как показано ниже:

    throw выражение

Значение выражения должно иметь тип, соответствующий протоколу Error.

Подробнее см. "Передача ошибки с помощью генерирующей функции" в разделе Обработка ошибок.

Грамматика инструкции throw

throw-statement → throw ­expression­

Инструкция defer

Инструкция defer используется для выполнения кода непосредственно перед передачей контроля программы за область, в которой используется инструкция defer.

Инструкция defer имеет следующий вид:

defer {
выражения
}

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

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

func f() {
    defer { print("First") }
    defer { print("Second") }
    defer { print("Third") }
}
f()
// Выведет "Third"
// Выведет "Second"
// Выведет "First"

Операторы в инструкции defer могут передавать управление программой за пределы инструкции defer.

Грамматика инструкции defer

defer-statement → defer­ code-block­

Инструкция do

Инструкция do используется, чтобы ввести новую область и может содержать один или несколько условий catch, содержащих шаблоны, соответствующих определенным условиям обработки ошибок. Переменные и константы, объявленные в области видимости инструкции do, будут доступны только в пределах этой области.

Инструкция do в Swift похожа на фигурные скобки ({}) в C и используется для разделения блока кода, и не снижает производительность во время выполнения.

Инструкция do выглядит так:

do {
try выражение
инструкции
} catch шаблон 1 {
инструкции
} catch шаблон 2 where условие {
инструкции
}

Как и инструкция switch, компилятор пытается сделать вывод о том, являются ли условия catch исчерпывающими. Если такое определение может быть сделано, то ошибка считается обработанной. В противном случае ошибка может распространиться из содержащей ее области, а это значит, что ошибка должна быть обработана с помощью включенного условия catch или содержащаяся функция должна быть объявлена ​​с throws.

Для того, чтобы убедиться, что ошибка обрабатывается, используйте условие catch с шаблоном, который подходит ко всем ошибкам, например шаблон (_). Если условие catch не указывает шаблон, то условие catch подходит и связывает любую ошибку локальной константы с именем error. Для получения дополнительной информации о шаблонах см. Шаблоны.

Подробнее об использовании инструкции do с условиями catch, см. Обработка ошибок.

Грамматика инструкции do

do-statement → do ­code-block­ catch-clauses­ opt­ catch-clauses → catch-clause ­catch-clauses­ opt­ catch-clause → catch­ pattern­ opt­ where-clause­ opt­ code-block­

Инструкции управления компиляторами

Инструкции управления компиляторами позволяют программе изменять аспекты поведения компилятора. В Swift есть две инструкции управления компиляторами: инструкция сборки конфигурации и инструкция управления строкой.

Грамматика инструкций управления компилятором

compiler-control-statement → conditional-compilation-block
compiler-control-statement → line-control-statement
compiler-control-statement → diagnostic-statement­

Блок условной компиляции

Блок условной компиляции позволяет коду быть условно скомпилированным в зависимости от значения одного или нескольких конфигураций сборки.

Каждый блок условной компиляции начинается с #if и заканчивается #endif. Простой блок условной компиляции выглядит так:

#if условие компиляции
выражения
#endif

В отличие от условия инструкции if, блок условной компиляции оценивается во время компиляции. В результате инструкции компилируются и выполняются только, если блок условной компиляции будет true во время компиляции.

Блок условной компиляции может включать в себя литералы логического типа true и false, идентификатор, используемый с флагом командной строки -D, или любую платформу или функцию тестирования версий языка, перечисленных в таблице ниже.

Условие платформы Действительные аргументы
os() macOS, iOS, watchOS, tvOS, Linux
arch() i386, x86_64, arm, arm64
swift() >= с последующим указанием номера версии
canImport() Имя модуля
targetEnvironment() simulator

Номер версии функций swift() и compiler() для установки платформенных условий состоит из главного числа, опционального минорного числа, опционального числа патча и по аналогии далее. Все эти числа разделяются символом точки, без каких-либо пробелов. Версия для compiler() является версией компилятора, независимо от параметра версии Swift, переданного компилятору. Версия для swift() - это языковая версия, которая в данный момент компилируется. Например, если вы компилируете свой код, используя компилятор Swift 5 в режиме Swift 4.2, версия компилятора будет 5, а языковая версия - 4.2. С этими настройками следующий код печатает все три сообщения:

#if compiler(>=5)
print("Compiled with the Swift 5 compiler or later")
#endif
#if swift(>=4.2)
print("Compiled in Swift 4.2 mode or later")
#endif
#if compiler(>=5) && swift(<5)
print("Compiled with the Swift 5 compiler or later in a Swift mode earlier than 5")
#endif
// Prints "Compiled with the Swift 5 compiler or later"
// Prints "Compiled in Swift 4.2 mode or later"
// Prints "Compiled with the Swift 5 compiler or later in a Swift mode earlier than 5"

Аргументом для условия canImport() является имя модуля, который может отсутствовать. Это условие проверяет, возможно ли импортировать модуль, но фактически не импортирует его. Если модуль присутствует, условие версии возвращает true; в противном случае он возвращает false.

Условие версии targetEnvironment() возвращает true, когда код скомпилирован для симулятора; в противном случае он возвращает false.

Заметка

Функция тестирования платформы arch(arm) не возвращает true для устройств ARM 64. Функция тестирования платформы arch(i386) возвращает true, если код скомпилирован для 32-битного iOS симулятора.

Вы можете комбинировать условие компиляции, используя логические операторы &&, ||, и ! и использовать круглые скобки для группировки.

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

#if условие компиляции 1
инструкции для компиляции, если условие компиляции 1 будет true
#elseif условие компиляции 2
инструкции для компиляции, если условие компиляции 2 будет true
#else
инструкции для компиляции, если условие компиляции 1 и 2 будет false
#endif

Заметка

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

Грамматика блока условной компиляции

conditional-compilation-block → if-directive-clause elseif-directive-clausesopt statementsopt 

if-directive-clause → if-directive compilation-condition statementsopt
elseif-directive-clauses→ elseif-directive-clause elseif-directive-clausesopt
elseif-directive-clause→ elseif-directive compilation-condition statementsopt
else-directive-clause → else-directivestatementsopt
if-directive → #if
‌elseif-directive → #elseif
‌else-directive → #else
‌endif-directive → #endif

compilation-condition → platform-condition
‌compilation-condition → identifier
‌compilation-condition → boolean-literal
‌compilation-condition → ( compilation-condition )
‌compilation-condition → ! compilation-condition
‌compilation-condition → compilation-condition && compilation-condition
‌compilation-condition → compilation-condition || compilation-condition

‌platform-condition → os ( operating-system )
‌platform-condition → arch ( architecture )
‌platform-condition → swift ( >= swift-version )
‌‌platform-condition → canImport ( module-name )
‌‌platform-condition → targetEnvironment ( environment )

operating-system → macOS | iOS | watchOS | tvOS
‌architecture → i386x86_64 |  | arm | arm64
‌swift-version → decimal-digits swift-version-continuationopt
swift-version-continuation → . decimal-digits swift-version-continuationopt
module-name → identifier
environment → simulator

Инструкция управления строкой

Инструкция управления строкой используется для указания номера строки и имени файла, которые могут отличаться от номера строки и имени файла исходного компилированного кода. Используйте инструкцию управления строкой для изменения локализации исходного кода, используемого в Swift для целей диагностики и отладки.

Инструкция управления строкой имеет следующий вид:

#sourceLocation(file: имя файла, line: номер строки)
#sourceLocation

Инструкция управления строкой изменяет значения #line и #file выражения литералов, начиная со строки кода после инструкции управления строкой. Номер строки изменяет значение #line и может быть любым целым числом больше нуля. Имя файла изменяет значение #file и является строковым литералом.

Вторая инструкция управления строкой, #sourceLocation (), сбрасывает исходный код и имя файла обратно по умолчанию.

Грамматика инструкции управления строкой

line-control-statement → #sourceLocation ( file: file-name,line:line-number)
‌line-control-statement → #sourceLocation ( )
‌line-number → Целое число большее нуля
‌file-name → static-string-literal

Диагностический оператор времени компиляции

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

#error("error message")
#warning("warning message")

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

Грамматика оператора диагностики времени компиляции

diagnostic-statement → #error ( diagnostic-message )
diagnostic-statement → #warning ( diagnostic-message )
diagnostic-message →static-string-literal

Условие доступности

Условие доступности используется в качестве условия инструкции if, while и guard для запроса доступности API во время выполнения, основываясь на аргументы указанных платформ.

Условие доступности выглядит так:

if #available (название платформы версия, ..., *) {
инструкции для исполнения, если API доступен
} else {
резервные инструкции на случай не доступности API
}

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

Условие доступности принимает список имен платформ и версий разделенных запятыми. Используйте iOS, OSX и watchOS в качестве названий платформ, и добавьте соответствующие номера версий к ним. Аргумент * является обязательным и указывает, что на любой другой платформе тело блока кода, охраняемого условием доступности, выполняется на минимальной deployment target (минимальная версия поддерживающая приложения), указанный в taget проекта.

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

Грамматика условий доступности

availability-condition → #available ( availability-arguments )
availability-arguments → availability-argument  |  availability-argument , availability-arguments
‌availability-argument → platform-name platform-version
‌availability-argument → *
‌platform-name → iOS  |  iOSApplicationExtension
‌platform-name → OSX  |  OSXApplicationExtension
‌platform-name → watchOS
‌platform-name → tvOS
‌platform-version → decimal-digits
‌platform-version → decimal-digits . decimal-digits
‌platform-version → decimal-digits . decimal-digits . decimal-digits

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: