Видеокурсы по изучению языка программирования Swift. Подробнее

Swift Language Reference: Шаблоны

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Шаблон представляет собой структуру одного значения или составного значения. Например, структура кортежа (1, 2) представляет собой разделенный запятыми список, состоящий из двух элементов. Поскольку шаблоны представляют структуру значения, а не какое-либо конкретное значение, вы можете сопоставить их с различными значениями. Например, шаблон (x, y) совпадает с кортежем (1, 2), а также с любым другим кортежем, состоящем из двух элементов. В дополнение к тому, что шаблон совпадает с значением, вы также можете извлечь часть или всё составное значение и связать каждую его часть с именем константы или переменной.

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

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

Второй вид шаблона используется для полного совпадения с шаблоном, где значение, с которым вы пытаетесь совпасть, может не находится там во время выполнения. Сюда включены шаблоны кейсов перечисления, опциональные шаблоны, шаблоны выражений и шаблоны приведения типов. Вы можете использовать эти шаблоны в ярлыках кейсов инструкции switch, в условии catch инструкции do, или в условии инструкции if, while, guard, или for-in.

Грамматика шаблонов

pattern wildcard-pattern type-annotationopt­
pattern identifier-pattern­ type-annotationopt­
pattern value-binding-pattern
pattern tuple-pattern­ type-annotation­opt­
pattern enum-case-pattern­
pattern optional-pattern­
pattern type-casting-pattern­
pattern expression-pattern­

Шаблон wildcard

Шаблон wildcard совпадает и игнорирует любое значение и состоит из знака подчеркивания (_). Используйте этот шаблон, когда вам не важно имя, в которое присваивается значение. Например, следующий код перебирает в закрытом диапазоне 1...3, игнорируя текущее значение диапазона в каждой итерации цикла:

for _ in 1...3 {
   // делаем что-то три раза
}

Грамматика шаблона wildcard

wildcard-pattern

Шаблон идентификатора

Шаблон идентификатора совпадает с любым значением и связывает совпавшее значение с именем переменной или константы. Например, в следующем объявлении константы, someValue является шаблоном идентификатора, который совпадает со значением 42 типа Int:

let someValue = 42

Когда совпадение проходит успешно, значение 42 связывается с именем константы someValue.

Когда шаблон на левой стороне переменной или объявления константы является шаблоном идентификатора, шаблон идентификатора является неявным подшаблоном шаблона присваивания значения.

Грамматика шаблона идентификатора

identifier-pattern identifier

Шаблон присваивания значения

Шаблон присваивания значения связывает соответствующие значения с именами переменных или констант. Шаблоны присваивания значения, связывают совпавшее значение с именем константы, которое начинается с ключевого слова let, а те, которые связываются с именем переменной начинается с ключевого слова var.

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

let point = (3, 2)
switch point {
   // Связываем x и y с координатами точки
   case let (x, y):
      print("Точка имеет координаты (\(x), \(y)).")
}
// Выведет "Точка имеет координаты (3, 2)."

В приведенном выше примере let распространяется на каждый шаблон идентификатора в шаблоне кортежа (x, y). Из-за такого поведения, кейсы switch case let (x, y): и case (let x, let y): совпадают с одними и теме же значениями.

Грамматика шаблона присваивающего значение

value-binding-pattern var­ pattern­ let­ pattern­

Шаблон кортежа

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

Вы можете ограничить шаблон кортежа, чтобы он соответствовал определенным видам типов кортежа, используя аннотации типа. Например, шаблон кортежа (x, y): (Int, Int) в объявлении константы let (x, y): (Int, Int) = (1, 2) совпадает только с типами кортежа, в которых оба элемента типа Int.

Когда шаблон кортежа используется в качестве шаблона в инструкции for-in или в объявлении переменной или константы, он может содержать только шаблоны wildcard, шаблоны идентификаторов, опциональные шаблоны или другие шаблоны кортежей их содержащие. Например, следующий код не является рабочим, потому что элемент 0 в шаблоне кортежа (x, 0) является шаблоном выражения:

let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
// Код не является рабочим
for (x, 0) in points {
   /* ... */
}

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

let a = 2        // a: Int = 2
let (a) = 2      // a: Int = 2
let (a): Int = 2 // a: Int = 2

Грамматика шаблона кортежа

tuple-pattern (­ tuple-pattern-element-list­opt ­) ­
tuple-pattern-element-list tuple-pattern-element­ | tuple-pattern-element­,­ tuple-pattern-element-list­
tuple-pattern-element pattern­ | identifier­ :­ pattern­

Шаблон перечисления кейса

Шаблон перечисления кейса совпадает с кейсом существующего типа перечисления. Шаблоны перечисления кейса появляются в ярлыках кейсов инструкции switch и в условиях кейсов инструкции if, while, guard, и for-in.

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

Грамматика кейса перечисления

enum-case-pattern type-identifier­opt­ .­ enum-case-name ­tuple-pattern­opt­

Шаблон опционала

Шаблон опционала совпадает со значениями, завернутыми в кейс some(Wrapped) перечисления Optional<Wrapped>. Опциональные шаблоны состоят из шаблона идентификатора, за которым сразу следует знак вопроса и встречаются они в тех же местах, где и шаблоны кейсов перечисления.

Поскольку опциональные шаблоны являются синтаксическим сахаром для Optional шаблонов кейсов перечисления, следующее является эквивалентным:

let someOptional: Int? = 42
// Сравнение с использованием шаблона кейса перечисления
if case .some(let x) = someOptional {
   print(x)
}
 
// Сравнение с использованием шаблоном опционала
if case let x? = someOptional {
   print(x)
}

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

let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
// Отметить только не nil значения
for case let number? in arrayOfOptionalInts {
   print("Найдено \(number)")
}
// Найдено 2
// Найдено 3
// Найдено 5

Грамматика опционального шаблона

optional-pattern identifier-pattern­

Шаблоны приведения типов

Существуют два шаблона приведения типов: шаблон is и шаблон as. Шаблон is появляется только в ярлыках кейса инструкции switch. Шаблоны is и as имеют следующий вид:

is тип
шаблон as тип

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

Шаблон as совпадает со значением, если тип этого значения во время выполнения программы является таким же, как и тип, указанный в правой части шаблона as или подклассе этого типа. Если совпадение найдено, то тип совпавшего значения приводится к шаблону, указанному в левой части шаблона as.

Для примера того, как используется инструкция switch для совпадения значений с шаблонами is и as см. Приведение типов для Any и AnyObject.

Грамматика шаблона приведения типа

type-casting-pattern is-pattern­ as-pattern­
is-pattern is­ type
as-pattern pattern­ as­ type

Шаблон выражения

Шаблон выражения представляет собой значение выражения. Шаблоны выражения появляются только в ярлыках кейсов инструкции switch.

Выражение, представленное шаблоном выражения, сравнивается со значением входного выражения с помощью оператора стандартной библиотеки Swift ~= . Совпадение проходит успешно, если оператор ~=  возвращает true. По умолчанию оператор ~= сравнивает два значения одного и того же типа с помощью оператора ==. Также может быть совпадение со значением интеджера и диапазоном целых чисел в объекте Range, как показывает следующий пример:

let point = (1, 2)
switch point {
   case (0, 0):
      print("(0, 0) является точкой отсчета.")
   case (-2...2, -2...2):
      print("(\(point.0), \(point.1)) находится рядом с точкой отсчета.")
   default:
      print("Точка имеет координаты (\(point.0), \(point.1)).")
}
// Выведет "(1, 2)находится рядом с точкой отсчета."

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

// Перезагрузка оператора ~= для соответствия строке и целочисленному значению
func ~=(pattern: String, value: Int) -> Bool {
   return pattern == "\(value)"
}
switch point {
   case ("0", "0"):
      print("(0, 0) является точкой отсчета.")
   default:
      print("Точка имеет координаты (\(point.0), \(point.1)).")
}
// Выведет "Точка имеет координаты (1, 2)."

Грамматика шаблона выражения

expression-pattern expression

Swift: 
3.0