Какой тип диспетчеризации используется у дженериков (обобщений) в Swift?

«Какой тип диспетчеризации используется у дженериков (обобщений) в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Дженерики (generics) в Swift используют статическую диспетчеризацию (static dispatch). Компилятор создает специализированные версии кода для каждого конкретного типа, что позволяет разрешать все вызовы на этапе компиляции.

Как это работает:

// Обобщенная функция
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var int1 = 100, int2 = 200
var str1 = "Hello", str2 = "World"

// Компилятор генерирует две специализированные функции:
// swapTwoValues<Int> и swapTwoValues<String>
swapTwoValues(&int1, &int2) // Статический вызов для Int
swapTwoValues(&str1, &str2) // Статический вызов для String

Преимущества:

  • Максимальная производительность: Нет накладных расходов на поиск в runtime.
  • Возможность оптимизаций: Компилятор может применять инлайнинг и другие оптимизации.
  • Безопасность типов: Полная проверка типов на этапе компиляции.

Ограничение: Нельзя напрямую использовать с протоколами, имеющими Self-требования или associatedtype, так как это требует динамической диспетчеризации (для таких случаев используют any или some).