Лексическая структура
Используйте компоненты синтаксиса на самом низком уровне.
Лексическая структура Swift описывает последовательность символов, формирующих допустимые токены языка. Эти допустимые токены образуют базовые строительные блоки языка и используются для описания остальной части языка в последующих главах. Токен состоит из идентификатора, ключевого слова, знака препинания, литерала или оператора.
В большинстве случаев токены генерируются из символов файла исходного кода Swift, рассматривая самую длинную возможную подстроку из входного текста, в рамках ограничений грамматики, которые указаны ниже. Это поведение называется самым длинным соответствием или максимальным соответствием.
Пробелы и комментарии
Пробелы используются для разделения токенов в исходном файле и для различения префиксных, постфиксных и инфиксных операторов (см. <doc:LexicalStructure#Operators>), но в остальном игнорируются. Следующие символы считаются пробелами: пробел (U+0020), перевод строки (U+000A), возврат каретки (U+000D), горизонтальная табуляция (U+0009), вертикальная табуляция (U+000B), подача страницы (U+000C) и нуль (U+0000).
Комментарии рассматриваются как пробелы компилятором. Однострочные комментарии начинаются с // и продолжаются до перевода строки (U+000A) или возврата каретки (U+000D). Многострочные комментарии начинаются с /* и заканчиваются */. Вложенность многострочных комментариев разрешена, но маркеры комментариев должны быть сбалансированы.
Комментарии могут содержать дополнительную форматирование и разметку, как описано в Справочнике по форматированию разметки.
Грамматика пробелов:
whitespace → whitespace-item whitespace_?_
whitespace-item → line-break
whitespace-item → inline-space
whitespace-item → comment
whitespace-item → multiline-comment
whitespace-item → U+0000, U+000B или U+000Cline-break → U+000A
line-break → U+000D
line-break → U+000D за которым следует U+000Ainline-spaces → inline-space inline-spaces_?_
inline-space → U+0009 или U+0020comment →
//comment-text line-break
multiline-comment →/*multiline-comment-text*/comment-text → comment-text-item comment-text_?_
comment-text-item → Любое скалярное значение Unicode, кроме U+000A или U+000Dmultiline-comment-text → multiline-comment-text-item multiline-comment-text_?_
multiline-comment-text-item → multiline-comment
multiline-comment-text-item → comment-text-item
multiline-comment-text-item → Любое скалярное значение Unicode, кроме/*или*/
Идентификаторы
Идентификаторы начинаются с заглавной или строчной буквы A–Z, символа подчёркивания (_), некомбинируемого буквенно-цифрового символа Unicode в базовой многоязычной плоскости или символом за пределами базовой многоязычной плоскости, который не находится в области частного использования. После первого символа также разрешены цифры и комбинирующие символы Unicode.
Идентификаторы, начинающиеся с символа подчёркивания, индексы, у которых метка первого аргумента начинается с символа подчёркивания, и инициализаторы, у которых метка первого аргумента начинается с символа подчёркивания, рассматриваются как внутренние, даже если их объявление имеет модификатор доступа public. Эта конвенция позволяет авторам фреймворков помечать часть API, с которой клиенты не должны взаимодействовать или на которую не должны полагаться, даже если для объявления требуется публичный доступ. Кроме того, идентификаторы, начинающиеся с двух символов подчёркивания, зарезервированы для компилятора Swift и стандартной библиотеки.
Чтобы использовать зарезервированное слово в качестве идентификатора, поместите обратный апостроф (`) перед и после него. Например, class — недопустимый идентификатор, но `class` — допустимый. Обратные апострофы не считаются частью идентификатора; `x` и x имеют одинаковое значение.
Внутри замыкания без явных имён параметров параметры неявно называются $0, $1, $2 и так далее. Эти имена являются допустимыми идентификаторами в рамках области действия замыкания.
Компилятор синтезирует идентификаторы, начинающиеся с символа доллара ($) для свойств, имеющих проекцию обертки свойства. Ваш код может взаимодействовать с этими идентификаторами, но вы не можете объявлять идентификаторы с этим префиксом. Дополнительную информацию см. в разделе <doc:Attributes#propertyWrapper> главы Атрибуты.
Грамматика идентификатора:
identifier → identifier-head identifier-characters_?_
identifier →`identifier-head identifier-characters_?_`
identifier → implicit-parameter-name
identifier → property-wrapper-projection
identifier-list → identifier | identifier,identifier-listidentifier-head → Заглавная или строчная буква A–Z
identifier-head →_
identifier-head → U+00A8, U+00AA, U+00AD, U+00AF, U+00B2–U+00B5, или U+00B7–U+00BA
identifier-head → U+00BC–U+00BE, U+00C0–U+00D6, U+00D8–U+00F6, или U+00F8–U+00FF
identifier-head → U+0100–U+02FF, U+0370–U+167F, U+1681–U+180D, или U+180F–U+1DBF
identifier-head → U+1E00–U+1FFF
identifier-head → U+200B–U+200D, U+202A–U+202E, U+203F–U+2040, U+2054, или U+2060–U+206F
identifier-head → U+2070–U+20CF, U+2100–U+218F, U+2460–U+24FF, или U+2776–U+2793
identifier-head → U+2C00–U+2DFF или U+2E80–U+2FFF
identifier-head → U+3004–U+3007, U+3021–U+302F, U+3031–U+303F, или U+3040–U+D7FF
identifier-head → U+F900–U+FD3D, U+FD40–U+FDCF, U+FDF0–U+FE1F, или U+FE30–U+FE44
identifier-head → U+FE47–U+FFFD
identifier-head → U+10000–U+1FFFD, U+20000–U+2FFFD, U+30000–U+3FFFD, или U+40000–U+4FFFD
identifier-head → U+50000–U+5FFFD, U+60000–U+6FFFD, U+70000–U+7FFFD, или U+80000–U+8FFFD
identifier-head → U+90000–U+9FFFD, U+A0000–U+AFFFD, U+B0000–U+BFFFD, или U+C0000–U+CFFFD
identifier-head → U+D0000–U+DFFFD или U+E0000–U+EFFFDidentifier-character → Цифра от 0 до 9
identifier-character → U+0300–U+036F, U+1DC0–U+1DFF, U+20D0–U+20FF, или U+FE20–U+FE2F
identifier-character → identifier-head
identifier-characters → identifier-character identifier-characters_?_implicit-parameter-name →
$decimal-digits
property-wrapper-projection →$identifier-characters
Ключевые слова и знаки препинания
Следующие ключевые слова зарезервированы и не могут использоваться в качестве идентификаторов, если не экранированы с помощью обратных апострофов, как описано выше в <doc:LexicalStructure#Identifiers>. Ключевые слова, кроме inout, var и let, могут использоваться в качестве имён параметров в объявлении функции или вызове функции без экранирования обратными апострофами. Когда член имеет такое же имя, как ключевое слово, ссылки на этот член не требуют экранирования обратными апострофами, за исключением случаев неоднозначности между ссылкой на член и использованием ключевого слова — например, self, Type и Protocol имеют специальное значение в явном выражении члена, поэтому они должны быть экранированы обратными апострофами в этом контексте.
- Ключевые слова, используемые в объявлениях:
associatedtype,borrowing,class,consuming,deinit,enum,extension,fileprivate,func,import,init,inout,internal,let,nonisolated,open,operator,precedencegroup,private,protocol,public,rethrows,static,struct,subscript,typealiasиvar.
- Ключевые слова, используемые в операциях:
break,case,catch,continue,default,defer,do,else,fallthrough,for,guard,if,in,repeat,return,switch,throw,whereиwhile. - Ключевые слова, используемые в выражениях и типах:
Any,as,await,catch,false,is,nil,rethrows,self,Self,super,throw,throws,trueиtry. - Ключевые слова, используемые в шаблонах:
_. - Ключевые слова, начинающиеся со знака номера (
#):#available,#colorLiteral,#else,#elseif,#endif,#fileLiteral,#if,#imageLiteral,#keyPath,#selector,#sourceLocation,#unavailable.
Примечание: До Swift 5.9 следующие ключевые слова были зарезервированы:
#column,#dsohandle,#error,#fileID,#filePath,#file,#function,#lineи#warning. Теперь они реализованы как макросы в стандартной библиотеке Swift:column,dsohandle,error(_:),fileID,filePath,file,function,line, иwarning(_:).
- Ключевые слова, зарезервированные в конкретных контекстах:
associativity,async,convenience,didSet,dynamic,final,get,indirect,infix,lazy,left,mutating,none,nonmutating,optional,override,package,postfix,precedence,prefix,Protocol,required,right,set,some,Type,unowned,weakиwillSet. Вне контекста, в котором они появляются в грамматике, их можно использовать в качестве идентификаторов.
Следующие токены зарезервированы как знаки препинания и не могут использоваться как пользовательские операторы: (, ), {, }, [, ], ., ,, :, ;, =, @, #, & (как префиксный оператор), ->, `, ? и ! (как постфиксный оператор).
Литералы
Литерал — это представление значения типа в исходном коде, например, число или строка.
Вот несколько примеров литералов:
42 // Integer literal 3.14159 // Floating-point literal "Hello, world!" // String literal /Hello, .*/ // Regular expression literal true // Boolean literal
У литерала нет собственного типа. Вместо этого литерал анализируется как имеющий бесконечную точность, и система вывода типов Swift пытается определить тип для литерала. Например, в объявлении let x: Int8 = 42, Swift использует явное указание типа (: Int8) для вывода, что тип целочисленного литерала 42 — это Int8. Если нет подходящей информации о типе, Swift выводит, что тип литерала — один из стандартных типов литералов, определённых в стандартной библиотеке Swift и перечисленных в таблице ниже. При указании аннотации типа для значения литерала тип аннотации должен быть типом, который может быть создан из этого значения литерала. То есть тип должен соответствовать протоколам стандартной библиотеки Swift, перечисленным в таблице ниже.
| Литерал | Тип по умолчанию | Протокол |
|---|---|---|
| Целое число | Int | ExpressibleByIntegerLiteral |
| Число с плавающей точкой | Double | ExpressibleByFloatLiteral |
| Строка | String |
ExpressibleByStringLiteral, ExpressibleByUnicodeScalarLiteral для строковых литералов, содержащих только один скаляр Unicode, ExpressibleByExtendedGraphemeClusterLiteral для строковых литералов, содержащих только один расширенный графемный кластер |
| Регулярное выражение | Regex | Нет |
| Булево значение | Bool | ExpressibleByBooleanLiteral |
Например, в объявлении let str = "Hello, world" тип строки "Hello, world" по умолчанию — это String. Также Int8 соответствует протоколу ExpressibleByIntegerLiteral, поэтому он может использоваться в аннотации типа для целочисленного литерала 42 в объявлении let x: Int8 = 42.
Грамматика литерала:
литерал → числовой-литерал | строковый-литерал | регулярное-выражение-литерал | булево-литерал | nil-литерал
числовой-литерал →
-_?_ целочисленный-литерал |-_?_ число-с-плавающей-точкой-литерал
булево-литерал →true|false
nil-литерал →nil
Целочисленные литералы
Целочисленные литералы представляют целочисленные значения неопределенной точности. По умолчанию целочисленные литералы записываются в десятичной форме; вы можете указать другую систему счисления, используя префикс. Двоичные литералы начинаются с 0b, восьмеричные — с 0o, и шестнадцатеричные — с 0x.
Десятичные литералы содержат цифры от 0 до 9. Двоичные литералы содержат 0 и 1, восьмеричные — от 0 до 7, а шестнадцатеричные — от 0 до 9, а также A и F в верхнем или нижнем регистре.
Отрицательные целочисленные литералы выражаются путём добавления знака минус (-) перед целочисленным литералом, как в -42.
Подчёркивания (_) разрешены между цифрами для удобочитаемости, но они игнорируются и, следовательно, не влияют на значение литерала. Целочисленные литералы могут начинаться с ведущих нулей (0), но они также игнорируются и не влияют на систему счисления или значение литерала.
Если не указано иное, тип целочисленного литерала по умолчанию — тип Int стандартной библиотеки Swift. Стандартная библиотека Swift также определяет типы для целых чисел различных размеров со знаком и без знака, как описано в <doc:TheBasics#Integers>.
Грамматика целочисленного литерала:
целочисленный-литерал → двоичный-литерал
целочисленный-литерал → восьмеричный-литерал
целочисленный-литерал → десятичный-литерал
целочисленный-литерал → шестнадцатеричный-литералдвоичный-литерал →
0bдвоичная-цифра двоичные-символы-литерала_?_
двоичная-цифра → Цифра 0 или 1
двоичный-символ-литерала → двоичная-цифра |_
двоичные-символы-литерала → двоичный-символ-литерала двоичные-символы-литерала_?_восьмеричный-литерал →
0oвосьмеричная-цифра восьмеричные-символы-литерала_?_
восьмеричная-цифра → Цифра от 0 до 7
восьмеричный-символ-литерала → восьмеричная-цифра |_
восьмеричные-символы-литерала → восьмеричный-символ-литерала восьмеричные-символы-литерала_?_десятичный-литерал → десятичная-цифра десятичные-символы-литерала_?_
десятичная-цифра → Цифра от 0 до 9
десятичные-цифры → десятичная-цифра десятичные-цифры_?_
десятичный-символ-литерала → десятичная-цифра |_
десятичные-символы-литерала → десятичный-символ-литерала десятичные-символы-литерала_?_шестнадцатеричный-литерал →
0xшестнадцатеричная-цифра шестнадцатеричные-символы-литерала_?_
шестнадцатеричная-цифра → Цифра от 0 до 9, a–f или A–F
шестнадцатеричный-символ-литерала → шестнадцатеричная-цифра |_
шестнадцатеричные-символы-литерала → шестнадцатеричный-символ-литерала шестнадцатеричные-символы-литерала_?_
Литералы с плавающей точкой
Литералы с плавающей точкой представляют значения с плавающей точкой неопределенной точности.
По умолчанию литералы с плавающей точкой записываются в десятичной форме (без префикса), но их также можно записать в шестнадцатеричной форме (с префиксом 0x).
Десятичные литералы с плавающей точкой состоят из последовательности десятичных цифр, за которыми следует либо десятичная дробь, либо десятичный показатель, или оба. Десятичная дробь состоит из десятичной точки (.) и последовательности десятичных цифр. Показатель состоит из префикса e (в верхнем или нижнем регистре) и последовательности десятичных цифр, указывающих на степень 10, на которую умножается значение перед e. Например, 1.25e2 представляет 1,25 × 10², что равно 125.0. Аналогично, 1.25e-2 представляет 1,25 × 10⁻², что равно 0.0125.
Шестнадцатеричные литералы с плавающей точкой состоят из префикса 0x, за которым следует необязательная шестнадцатеричная дробь и шестнадцатеричный показатель. Шестнадцатеричная дробь состоит из десятичной точки и последовательности шестнадцатеричных цифр. Показатель состоит из префикса p (в верхнем или нижнем регистре) и последовательности десятичных цифр, указывающих на степень 2, на которую умножается значение перед p. Например, 0xFp2 представляет 15 × 2², что равно 60. Аналогично, 0xFp-2 представляет 15 × 2⁻², что равно 3.75.
Отрицательные литералы с плавающей точкой выражаются путём добавления знака минус (-) перед литералом с плавающей точкой, как в -42.5.
Подчеркивания (_) допускаются между цифрами для повышения читабельности, но они игнорируются и, следовательно, не влияют на значение литерала. Литералы с плавающей точкой могут начинаться с ведущих нулей (0), но они также игнорируются и не влияют на основание или значение литерала.
Если не указано иное, тип по умолчанию, определяемый для литерала с плавающей точкой, — это стандартный тип библиотеки Swift Double, который представляет 64-битное число с плавающей точкой. Библиотека Swift также определяет тип Float, который представляет 32-битное число с плавающей точкой.
Грамматика литерала с плавающей точкой:
floating-point-literal → decimal-literal decimal-fraction_?_ decimal-exponent_?_
floating-point-literal → hexadecimal-literal hexadecimal-fraction_?_ hexadecimal-exponentdecimal-fraction →
.decimal-literal
decimal-exponent → floating-point-e sign_?_ decimal-literalhexadecimal-fraction →
.hexadecimal-digit hexadecimal-literal-characters_?_
hexadecimal-exponent → floating-point-p sign_?_ decimal-literalfloating-point-e →
e|E
floating-point-p →p|P
sign →+|-
Литералы строк
Литерал строки — это последовательность символов, заключённых в кавычки. Литерал строки одной строки заключён в двойные кавычки и имеет следующий вид:
"<#characters#>"
Литералы строк не могут содержать незаменённую двойную кавычку ("), незаменённый обратный слэш (\), возврат каретки или перевод строки.
Многострочный литерал строки заключён в три двойные кавычки и имеет следующий вид:
""" <#characters#> """
В отличие от однострочного литерала строки, многострочный литерал строки может содержать незаменённые двойные кавычки ("), возврат каретки и перевод строки. Он не может содержать три незаменённых двойные кавычки подряд.
Перевод строки после """, начинающей многострочный литерал строки, не является частью строки. Перевод строки перед """, завершающей литерал, также не является частью строки. Чтобы создать многострочный литерал строки, начинающийся или заканчивающийся переводом строки, напишите пустую строку как первую или последнюю строку.
Многострочный литерал строки можно отступать, используя любую комбинацию пробелов и табуляции; этот отступ не включается в строку. """, завершающий литерал, определяет отступ: каждая непустая строка в литерале должна начинаться с ровно того же отступа, что и перед закрывающей """; преобразования между табуляцией и пробелами не происходит. Вы можете добавить дополнительные пробелы и табуляции после этого отступа; эти пробелы и табуляции появятся в строке.
Переводы строк в многострочном литерале строки нормализуются с использованием символа перевода строки. Даже если ваш исходный файл содержит смесь возвратов каретки и переводов строки, все переводы строк в строке будут одинаковыми.
В многострочном литерале строки написание обратного слэша (\) в конце строки опускает перевод строки из строки. Любые пробелы между обратным слэшем и переводом строки также опускаются. Вы можете использовать этот синтаксис для форматирования многострочного литерала строки в вашем исходном коде, не изменяя значение результирующей строки.
Специальные символы могут быть включены в литералы строк как в однострочном, так и в многострочном форматах с помощью следующих последовательностей escape:
- Нулевой символ (
\0) - Обратный слэш (
\\) - Горизонтальная табуляция (
\t) - Перевод строки (
\n) - Возврат каретки (
\r) - Двойная кавычка (
\") - Одинарная кавычка (
\') - Скаляр Unicode (
\u{n}), где n — шестнадцатеричное число, имеющее от одной до восьми цифр
Значение выражения можно вставить в литерал строки, поместив выражение в скобки после обратного слэша (\). Вставляемое выражение может содержать литерал строки, но не может содержать незаменённый обратный слэш, возврат каретки или перевод строки.
Например, все следующие литералы строк имеют одинаковое значение:
"1 2 3"
"1 2 \("3")"
"1 2 \(3)"
"1 2 \(1 + 2)"
let x = 3; "1 2 \(x)" Строка, ограниченная расширенными разделителями, — это последовательность символов, окружённых кавычками и сбалансированным набором одного или нескольких знаков числа (#). Строка, ограниченная расширенными разделителями, имеет следующие формы:
#"<#characters#>"# #""" <#characters#> """#
Специальные символы в строке, ограниченной расширенными разделителями, появляются в результирующей строке как обычные символы, а не как специальные символы. Вы можете использовать расширенные разделители для создания строк с символами, которые обычно имеют специальное действие, например, для генерации интерполяции строк, начала последовательности escape или завершения строки.
Следующий пример демонстрирует литерал строки и строку, ограниченную расширенными разделителями, которые создают эквивалентные значения строк:
let string = #"\(x) \ " \u{2603}"#
let escaped = "\\(x) \\ \" \\u{2603}"
print(string)
// Prints "\(x) \ " \u{2603}"
print(string == escaped)
// Prints "true" Если вы используете более одного знака числа для формирования строки, ограниченной расширенными разделителями, не помещайте пробелы между знаками числа:
print(###"Line 1\###nLine 2"###) // OK print(# # #"Line 1\# # #nLine 2"# # #) // Error
Многострочные литералы строк, созданные с использованием расширенных разделителей, имеют те же требования к отступам, что и обычные многострочные литералы строк.
Тип строки по умолчанию, выводимый для литерала строки, — String. Дополнительную информацию о типе String см. в StringsAndCharacters и String.
Литералы строк, которые конкатенируются оператором +, конкатенируются во время компиляции. Например, значения textA и textB в приведённом ниже примере идентичны — никакой конкатенации во время выполнения не выполняется.
let textA = "Hello " + "world" let textB = "Hello world"
Грамматика литерала строки:
string-literal → static-string-literal | interpolated-string-literal
string-literal-opening-delimiter → extended-string-literal-delimiter_?_
"
string-literal-closing-delimiter →"extended-string-literal-delimiter_?_static-string-literal → string-literal-opening-delimiter quoted-text_?_ string-literal-closing-delimiter
static-string-literal → multiline-string-literal-opening-delimiter multiline-quoted-text_?_ multiline-string-literal-closing-delimitermultiline-string-literal-opening-delimiter → extended-string-literal-delimiter_?_
"""
multiline-string-literal-closing-delimiter →"""extended-string-literal-delimiter_?_
extended-string-literal-delimiter →#extended-string-literal-delimiter_?_quoted-text → quoted-text-item quoted-text_?_
quoted-text-item → escaped-character
quoted-text-item → Любой скаляр Unicode, кроме",\, U+000A или U+000Dmultiline-quoted-text → multiline-quoted-text-item multiline-quoted-text_?_
multiline-quoted-text-item → escaped-character
multiline-quoted-text-item → Любой скаляр Unicode, кроме\
multiline-quoted-text-item → escaped-newlineinterpolated-string-literal → string-literal-opening-delimiter interpolated-text_?_ string-literal-closing-delimiter
interpolated-string-literal → multiline-string-literal-opening-delimiter multiline-interpolated-text_?_ multiline-string-literal-closing-delimiterinterpolated-text → interpolated-text-item interpolated-text_?_
interpolated-text-item →\(expression)| quoted-text-itemmultiline-interpolated-text → multiline-interpolated-text-item multiline-interpolated-text_?_
multiline-interpolated-text-item →\(expression)| multiline-quoted-text-itemescape-sequence →
\extended-string-literal-delimiter
escaped-character → escape-sequence0| escape-sequence\| escape-sequencet| escape-sequencen| escape-sequencer| escape-sequence"| escape-sequence'
escaped-character → escape-sequenceu{unicode-scalar-digits}
unicode-scalar-digits → От одной до восьми шестнадцатеричных цифрescaped-newline → escape-sequence inline-spaces_?_ line-break
Литералы регулярных выражений
Литерал регулярного выражения — это последовательность символов, окружённых слэшами (/) с следующим видом:
/<#regular expression#>/
Литералы регулярных выражений не должны начинаться с незаменённой табуляции или пробела, и они не могут содержать незаменённый слэш (/), возврат каретки или перевод строки.
Внутри литерала регулярного выражения обратный слэш понимается как часть этого регулярного выражения, а не просто как символ escape, как в литералах строк. Он указывает, что следующий специальный символ должен интерпретироваться буквально, или что следующий неспециальный символ должен интерпретироваться особым образом. Например, /\(/ соответствует одной левой скобке, а /\d/ соответствует одной цифре.
Литерал регулярного выражения, ограниченный расширенными разделителями, представляет собой последовательность символов, заключённых в косые черты (/) и сбалансированным набором одного или нескольких знаков числа (#). Литерал регулярного выражения, ограниченный расширенными разделителями, имеет следующие формы:
#/<#regular expression#>/# #/ <#regular expression#> /#
Литерал регулярного выражения, использующий расширенные разделители, может начинаться с неэкранированного пробела или табуляции, содержать неэкранированные косые черты (/) и занимать несколько строк. Для многострочного литерала регулярного выражения открывающий разделитель должен находиться в конце строки, а закрывающий разделитель — на отдельной строке. Внутри многострочного литерала регулярного выражения синтаксис расширенного регулярного выражения включён по умолчанию — в частности, пробелы игнорируются, а комментарии разрешены.
Если вы используете более одного знака числа для создания литерала регулярного выражения, ограниченного расширенными разделителями, не ставьте пробелы между знаками числа:
let regex1 = ##/abc/## // OK let regex2 = # #/abc/# # // Error
Если вам нужно создать пустой литерал регулярного выражения, вы должны использовать синтаксис расширенного разделителя.
Грамматика литерала регулярного выражения:
regular-expression-literal → regular-expression-literal-opening-delimiter regular-expression regular-expression-literal-closing-delimiter
regular-expression → Любое регулярное выражениеregular-expression-literal-opening-delimiter → extended-regular-expression-literal-delimiter_?_
/
regular-expression-literal-closing-delimiter →/extended-regular-expression-literal-delimiter_?_extended-regular-expression-literal-delimiter →
#extended-regular-expression-literal-delimiter_?_
Операторы
Стандартная библиотека Swift определяет ряд операторов для вашего использования, многие из которых обсуждаются в BasicOperators и AdvancedOperators. В данной секции описываются символы, которые могут использоваться для определения пользовательских операторов.
Пользовательские операторы могут начинаться с одного из ASCII-символов /, =, -, +, !, *, %, <, >, &, |, ^, ? или ~, или одним из Unicode-символов, определённых в грамматике ниже (включая символы из блоков Unicode Математические операторы, Разные символы и Значки, среди прочих). После первого символа также допускаются комбинированные Unicode-символы.
Вы также можете определять пользовательские операторы, которые начинаются с точки (.). Эти операторы могут содержать дополнительные точки. Например, .+. обрабатывается как один оператор. Если оператор не начинается с точки, он не может содержать точку в другом месте. Например, +.+ обрабатывается как оператор +, за которым следует оператор .+.
Хотя вы можете определять пользовательские операторы, содержащие знак вопроса (?), они не могут состоять только из одного символа знака вопроса. Кроме того, хотя операторы могут содержать знак восклицания (!), постфиксные операторы не могут начинаться ни со знака вопроса, ни со знака восклицания.
Примечание: Токены
=,->,//,/*,*/,., префиксные операторы<,&и?, инфиксный оператор?и постфиксные операторы>,!и?зарезервированы. Эти токены нельзя перегружать, а также нельзя использовать в качестве пользовательских операторов.
Пробелы вокруг оператора используются для определения, используется ли оператор как префиксный, постфиксный или инфиксный оператор. Это поведение определяется следующими правилами:
- Если у оператора есть пробелы с обеих сторон или ни с одной стороны, он обрабатывается как инфиксный оператор. Например, оператор
+++вa+++bиa +++ bобрабатывается как инфиксный оператор. - Если у оператора есть пробелы только слева, он обрабатывается как префиксный унарный оператор. Например, оператор
+++вa +++bобрабатывается как префиксный унарный оператор. - Если у оператора есть пробелы только справа, он обрабатывается как постфиксный унарный оператор. Например, оператор
+++вa+++ bобрабатывается как постфиксный унарный оператор. - Если у оператора нет пробелов слева, но за ним сразу следует точка (
.), он обрабатывается как постфиксный унарный оператор. Например, оператор+++вa+++.bобрабатывается как постфиксный унарный оператор (a+++ .b, а неa +++ .b).
Для целей этих правил символы (, [ и { перед оператором, символы ), ] и } после оператора и символы ,, ; и : также считаются пробелами.
Если предопределённый оператор ! или ? не имеет пробелов слева, он обрабатывается как постфиксный оператор, независимо от наличия пробелов справа. Чтобы использовать ? в качестве оператора необязательной цепочки, он не должен иметь пробелы слева. Чтобы использовать его в операторе условного выражения из трёх частей (? :), он должен иметь пробелы с обеих сторон.
Если одним из аргументов инфиксного оператора является литерал регулярного выражения, оператор должен иметь пробелы с обеих сторон.
В некоторых конструкциях операторы с ведущим < или > могут быть разделены на два или более токенов. Остальные части обрабатываются одинаково и могут быть разделены снова. В результате вам не нужно добавлять пробелы, чтобы устранить неоднозначность между закрывающими > символами в конструкциях, таких как Dictionary<String, Array<Int>>. В этом примере закрывающие > символы не обрабатываются как один токен, который может быть неправильно истолкован как оператор битового сдвига >>.
Чтобы узнать, как определять новые пользовательские операторы, см. <doc:AdvancedOperators#Custom-Operators> и <doc:Declarations#Operator-Declaration>. Чтобы узнать, как перегружать существующие операторы, см. <doc:AdvancedOperators#Operator-Methods>.
Грамматика операторов:
operator → operator-head operator-characters_?_
operator → dot-operator-head dot-operator-charactersoperator-head →
/|=|-|+|!|*|%|<|>|&|||^|~|?
operator-head → U+00A1–U+00A7
operator-head → U+00A9 or U+00AB
operator-head → U+00AC or U+00AE
operator-head → U+00B0–U+00B1
operator-head → U+00B6, U+00BB, U+00BF, U+00D7, or U+00F7
operator-head → U+2016–U+2017
operator-head → U+2020–U+2027
operator-head → U+2030–U+203E
operator-head → U+2041–U+2053
operator-head → U+2055–U+205E
operator-head → U+2190–U+23FF
operator-head → U+2500–U+2775
operator-head → U+2794–U+2BFF
operator-head → U+2E00–U+2E7F
operator-head → U+3001–U+3003
operator-head → U+3008–U+3020
operator-head → U+3030operator-character → operator-head
operator-character → U+0300–U+036F
operator-character → U+1DC0–U+1DFF
operator-character → U+20D0–U+20FF
operator-character → U+FE00–U+FE0F
operator-character → U+FE20–U+FE2F
operator-character → U+E0100–U+E01EF
operator-characters → operator-character operator-characters_?_dot-operator-head →
.
dot-operator-character →.| operator-character
dot-operator-characters → dot-operator-character dot-operator-characters_?_infix-operator → operator
prefix-operator → operator
postfix-operator → operator
This source file is part of the Swift.org open source project
Copyright © 2014 - 2025 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception