← Назад к вопросам

Что такое any?

1.8 Middle🔥 162 комментариев
#Язык Swift

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое any в Swift?

any — это ключевое слово в Swift, которое появилось в Swift 5.7 (в составе Swift 5.6 в ранних бетах) для явного указания экзистенциальных типов (existential types). Оно является частью инициативы по улучшению работы с протоколами и повышению читаемости кода, известной как "непрозрачные и экзистенциальные типы" (SE-0335, SE-0346).

Основная суть any

Когда вы используете протокол в качестве типа (например, let item: SomeProtocol), вы фактически создаёте экзистенциальный тип — "коробку", которая может хранить любой конкретный тип, соответствующий этому протоколу. Слово any делает это явным:

// Без any (до Swift 5.7)
let vehicle: Vehicle = Car()

// С any (Swift 5.7+)
let vehicle: any Vehicle = Car()

Почему это важно?

  1. Явность и читаемость: Код становится более понятным. Видя any, вы сразу понимаете, что работаете с экзистенциальным типом, а не с конкретным типом.

  2. Различие с some: any контрастирует с другим ключевым словом — some, которое обозначает непрозрачный тип (opaque type):

    // any: "хранит ЛЮБОЙ тип, соответствующий Vehicle"
    func getAnyVehicle() -> any Vehicle { return Car() }
    
    // some: "возвращает КОНКРЕТНЫЙ тип, соответствующий Vehicle, но скрытый"
    func getSomeVehicle() -> some Vehicle { return Car() }
    
  3. Производительность: Экзистенциальные типы (any) имеют накладные расходы:

    • Динамическая диспетчеризация: Вызовы методов происходят через таблицу виртуальных функций (vtable).
    • Выделение памяти: Может требовать выделения памяти в куче (heap allocation) для больших типов.
    • Не поддерживают специализированные операции: Нельзя использовать протоколы с Self или ассоциированные типы определённым образом.

Ключевые отличия any от конкретных типов

protocol Drawable {
    func draw()
}

struct Circle: Drawable {
    func draw() { print("Drawing circle") }
}

// С any
var shape: any Drawable = Circle()
shape = Square() // Можно присвоить другой тип

// Без any (конкретный тип)
var circle: Circle = Circle()
// circle = Square() // Ошибка: несовместимые типы

Ограничения any

  1. Невозможность использования с == для сравнения:

    let a: any Equatable = 5
    let b: any Equatable = 5
    // a == b // Ошибка: протокол 'Equatable' может использоваться только как общее ограничение
    
  2. Требует явного приведения типов:

    let shape: any Drawable = Circle()
    let circle = shape as! Circle // Явное приведение необходимо
    

Практические рекомендации

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

    let shapes: [any Drawable] = [Circle(), Square(), Triangle()]
    
  • Предпочитайте some когда возможно — это даёт преимущества в производительности и типобезопасности:

    func createShape() -> some Drawable {
        return Circle() // Компилятор знает конкретный тип
    }
    
  • Избегайте any в критичных к производительности местах из-за накладных расходов.

Эволюция языка

До Swift 5.7 использование any было опциональным, но начиная с Swift 6 оно станет обязательным для экзистенциальных типов. Уже сейчас компилятор выдаёт предупреждения, если any отсутствует там, где должен быть.

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

Что такое any? | PrepBro