Найти в Дзене
Даниил Зазулин

Swift. Type Erasure - сокрытие типов.

На самом деле мне на практике type erasure встречалось не так часто, но возможно где-то активно используется, так же иногда спрашивают про сокрытие типов на собесов. Статья является кратким конспектом видео с ютуба "Type Erasure (Стирание типов), Copy on write в Swift".

Начнем с примера обычной реализации протокола с associatedtype:

Когда класс просто имплементирует протокол, проблем нет:

-2

Когда же мы указываем для параметра условие, что он должен реализовывать протокол, получаем ошибку:

Ошибка. "Protocol 'ObjectMapper' can only be used as a generic constraint because it has Self or associated type requirements"
Ошибка. "Protocol 'ObjectMapper' can only be used as a generic constraint because it has Self or associated type requirements"

Для обхода этой ошибки существует обходной путь Type Erasure - стирание типов, он так же применяется в самом Swift для AnyHashable, AnyIterator, AnySequence, AnyCollection и т.д. Это делается в три шага.

1) Создаем имитацию абстрактного класса, который имплементирует наш протокол: 2) Создаем класс-обертку от _AnyMapperBox:

-4

2) Создаем класс-обертку от _AnyMapperBox:

-5

3) Создаем структуру, которая имеет параметр типа нашего "абстрактного" класса, при иницилизации используем уже класс-обертку

-6

Теперь посмотрим пример использования. Пусть у нас есть структура Article, словарь ArticleDict и соответственно нужно преобразовать входящий словарь в структуру:

-7

Для этого используем класс ArticleService, в котором мы будем использовать уже в качестве маппера нашу структуру с третьего шага:

-8

Теперь нам нужен создать маппер:

-9

Для наглядности создадим второй, где будет отличаться title:

-10

И наконец реализуем нашу задачу:

-11

Вот, что вывелось на экран:

-12

Жду ваших замечаний, предложений, всем добра!