Spec-Zone.ru › Swift Language

Обобщенные параметры и аргументы

Обобщите объявления, чтобы абстрагировать конкретные типы.

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

Для обзора обобщений в Swift см. Обобщения.

Определение обобщенных параметров

Определение обобщенных параметров указывает параметры типа обобщенного типа или функции, а также любые связанные ограничения и требования к этим параметрам. Определение обобщенных параметров заключено в угловые скобки (<>) и имеет следующий формат:

<<#generic parameter list#>>

Список обобщенных параметров — это список обобщенных параметров, разделенных запятыми, каждый из которых имеет следующий формат:

<#type parameter#>: <#constraint#>

Обобщенный параметр состоит из параметра типа, за которым может следовать ограничение. Параметр типа — это просто имя плейсхолдера типа (например, T, U, V, Key, Value и так далее). Вы можете получить доступ к параметрам типа (и любым связанным с ними типам) в остальной части объявления типа, функции или инициализатора, включая в сигнатуре функции или инициализатора.

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

func simpleMax<T: Comparable>(_ x: T, _ y: T) -> T {
    if x < y {
        return y
    }
    return x
}

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

simpleMax(17, 42) // T is inferred to be Int
simpleMax(3.14159, 2.71828) // T is inferred to be Double

Определения обобщенных «where»

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

where <#requirements#>

Требования в определении обобщенных «where» указывают, что параметр типа наследуется от класса или соответствует протоколу или композиции протоколов. Хотя определение обобщенных «where» предоставляет синтаксический сахар для выражения простых ограничений для параметров типа (например, <T: Comparable> эквивалентно <T> where T: Comparable и так далее), вы можете использовать его для задания более сложных ограничений для параметров типа и их связанных типов. Например, вы можете ограничить связанные типы параметров типа, чтобы они соответствовали протоколам. Например, <S: Sequence> where S.Iterator.Element: Equatable указывает, что S соответствует протоколу Sequence, а связанный тип S.Iterator.Element соответствует протоколу Equatable. Это ограничение гарантирует, что каждый элемент последовательности является эквивалентным.

Вы также можете указать требование о том, что два типа идентичны, используя оператор ==. Например, <S1: Sequence, S2: Sequence> where S1.Iterator.Element == S2.Iterator.Element выражает ограничения, что S1 и S2 соответствуют протоколу Sequence, и что элементы обеих последовательностей должны быть одного типа.

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

Определение обобщенных «where» может появляться как часть объявления, включающего параметры типа, или как часть объявления, вложенного внутри объявления, включающего параметры типа. Определение обобщенных «where» для вложенного объявления все еще может ссылаться на параметры типа окружающего объявления; однако, требования из этого определения обобщенных «where» применяются только к объявлению, где оно написано.

Если у окружающего объявления также есть определение обобщенных «where», требования обоих определений объединяются. В приведенном ниже примере startsWithZero() доступен только в том случае, если Element соответствует как протоколу SomeProtocol, так и протоколу Numeric.

extension Collection where Element: SomeProtocol {
    func startsWithZero() -> Bool where Element: Numeric {
        return first == .zero
    }
}

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

Для получения дополнительной информации об определениях обобщенных «where» и для просмотра примера в объявлении обобщенной функции см. <doc:Generics#Generic-Where-Clauses>.

Грамматика определения обобщенных параметров:

generic-parameter-clause → < generic-parameter-list >
generic-parameter-list → generic-parameter | generic-parameter , generic-parameter-list
generic-parameter → type-name
generic-parameter → type-name : type-identifier
generic-parameter → type-name : protocol-composition-type

generic-where-clause → where requirement-list
requirement-list → requirement | requirement , requirement-list
requirement → conformance-requirement | same-type-requirement

conformance-requirement → type-identifier : type-identifier
conformance-requirement → type-identifier : protocol-composition-type
same-type-requirement → type-identifier == type

Определение обобщенных аргументов

Определение обобщенных аргументов указывает аргументы типа обобщенного типа. Определение обобщенных аргументов заключено в угловые скобки (<>) и имеет следующий формат:

<<#generic argument list#>>

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

struct Dictionary<Key: Hashable, Value>: Collection, ExpressibleByDictionaryLiteral {
    /* ... */
}

Специализированная версия обобщенного типа Dictionary, Dictionary<String, Int>, формируется путем замены обобщенных параметров Key: Hashable и Value конкретными аргументами типа String и Int. Каждый аргумент типа должен удовлетворять всем ограничениям обобщенного параметра, который он заменяет, включая любые дополнительные требования, указанные в определении обобщенных «where». В приведенном выше примере параметр типа Key ограничен соответствием протоколу Hashable, и поэтому String также должен соответствовать протоколу Hashable.

Вы также можете заменить параметр типа аргументом типа, который сам по себе является специализированной версией обобщенного типа (при условии, что он удовлетворяет соответствующим ограничениям и требованиям). Например, вы можете заменить параметр типа Element в Array<Element> специализированной версией массива, Array<Int>, чтобы сформировать массив, элементы которого сами являются массивами целых чисел.

let arrayOfArrays: Array<Array<Int>> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Как упоминалось в <doc:GenericParametersAndArguments#Generic-Parameter-Clause>, для задания аргументов типа обобщенной функции или инициализатора не используется определение обобщенных аргументов.

Грамматика определения обобщенных аргументов:

generic-argument-clause → < generic-argument-list >
generic-argument-list → generic-argument | generic-argument , generic-argument-list
generic-argument → type

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API