Swift Academy · Урок

Предложения where в функциях

Добавляйте точные ограничения к обобщённым функциям.

Урок 2 из 413 шагов

«Предложения where в функциях» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

За пределами простых ограничений

Ограничение вроде <T: Collection> описывает сам T. Но иногда нужно ограничить связанные типы T, например его Element. Для этого используется условие where.

func sumInts<C: Collection>(_ c: C) -> Int where C.Element == Int {
    c.reduce(0, +)
}
print(sumInts([1, 2, 3]))

Требование равенства типов

where C.Element == Int требует, чтобы элементы коллекции имели именно тип Int, что позволяет выполнять операции, предназначенные для целых чисел.

func describe<C: Collection>(_ c: C) -> String where C.Element == Int {
    "Sum is " + String(c.reduce(0, +))
}
print(describe(Set([1, 2, 3])))

Требование протокола для элемента

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

func joinAll<C: Collection>(_ c: C) -> String
    where C.Element: CustomStringConvertible {
    c.map { $0.description }.joined(separator: ", ")
}
print(joinAll([1, 2, 3]))

where после сигнатуры

Условие where располагается между возвращаемым типом и телом функции. Ограничения внутри <> и условие where работают вместе.

func maxElement<C: Collection>(_ c: C) -> C.Element?
    where C.Element: Comparable {
    c.max()
}
print(maxElement([4, 9, 2])!)

Связь двух параметров типов

Условие where может связать типы элементов двух разных обобщений с помощью ==.

func combine<A: Collection, B: Collection>(_ a: A, _ b: B) -> [A.Element]
    where A.Element == B.Element {
    Array(a) + Array(b)
}
print(combine([1, 2], Set([3])))

Несколько условий where

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

func report<C: Collection>(_ c: C)
    where C.Element: Comparable, C.Element: CustomStringConvertible {
    if let m = c.max() { print("max:", m.description) }
}
report([5, 1, 9])

Ограничение вложенных связанных типов

Можно обратиться ещё глубже — например, потребовать определённые свойства элемента элемента при работе с вложенными коллекциями.

func flatten<C: Collection>(_ c: C) -> [Int]
    where C.Element: Collection, C.Element.Element == Int {
    c.flatMap { Array($0) }
}
print(flatten([[1, 2], [3]]))

where с элементами Equatable

Требование, чтобы элементы соответствовали Equatable, позволяет искать в обобщённой коллекции.

func indexOf<C: Collection>(_ x: C.Element, in c: C) -> C.Index?
    where C.Element: Equatable {
    c.firstIndex(of: x)
}
if let i = indexOf(2, in: [1, 2, 3]) { print("found") }

Методы обобщённых типов с where

Методы внутри обобщённых типов также используют where, часто чтобы добавлять поведение только для определённых типов элементов.

struct Wrap<T> {
    let items: [T]
    func total() -> Int where T == Int { items.reduce(0, +) }
}
print(Wrap(items: [1, 2, 3]).total())

Преимущество для удобства чтения

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

func first<C: Collection>(_ c: C) -> String
    where C.Element: CustomStringConvertible {
    c.first.map { $0.description } ?? "empty"
}
print(first([10, 20]))

where в стандартной библиотеке

Такие методы, как joined() для последовательностей последовательностей, используют внутри условия where, чтобы точно выразить свои требования.

let nested = [[1, 2], [3, 4]]
print(Array(nested.joined()))

Проверка понимания

Проверьте, насколько хорошо Вы поняли условия where для функций.

Итоги

Условия where позволяют ограничивать связанные типы обобщённого типа: требовать для элемента конкретный тип (== Int), соответствие протоколу (: Comparable), связывать элементы двух параметров или обращаться к вложенным связанным типам. Они располагаются после сигнатуры и делают сложные ограничения более понятными.

Можно начать бесплатно

Изучай Swift с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
122
Уроки
409

Часто задаваемые вопросы

Урок «Предложения where в функциях» бесплатный?

Да — полный текст урока «Предложения where в функциях» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Предложения where в функциях»?

Добавляйте точные ограничения к обобщённым функциям. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Предложения where в функциях»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Ограничения параметров типов
  2. Предложения where в функциях
  3. Ограничение ассоциированных типов
  4. Обобщённые индексы и расширения
← Назад к Swift Academy