Как во время выполнения Swift знает, какую реализацию использовать?

protocol A {
    func f()
}

struct S1 : A {
    func f() {
        print("S1")
    }
}

struct S2 : A {
    func f() {
        print("S2")
    }
}

let array: [A] = [S1(), S2()]

for s: A in array {
    s.f()
}

// "S1\n" "S2\n"

Если бы это была иерархия наследования, я бы ожидал, что Swift будет использовать v-таблицу для поиска правильной реализации. Тем не менее, конкретные типы в array может быть все, что реализует Aнаряду с любым количеством других протоколов, как бы среда выполнения Swift узнала структуру объекта, если бы он также использовал v-таблицы?

1 ответ

Решение

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

Майк Эш лучше всего объясняет это в своей статье " Изучение структуры памяти Swift, часть II:

Последний, по смещению 32, представляет собой "таблицу свидетелей протокола" для базового типа и протокола, которая содержит указатели на реализации типа методов протокола. Вот как компилятор может вызывать методы, такие как p(), для значения типа протокола, не зная базового типа во время выполнения.

Я также посмотрел бы видео WWDC " Понимание быстрой работы", как это было предложено в комментариях Хэмиша.

Другие вопросы по тегам