Как Swift определяет доступность соответствия публичного типа публичному протоколу, если оно объявлено во внутреннем extension?
Доступность соответствия не определяется уровнем доступа extension. Для соответствия протоколу Swift учитывает прежде всего доступность самого типа и протокола: она не может быть выше минимального уровня этих двух сущностей. Поэтому соответствие публичного типа публичному протоколу может быть доступно клиентскому модулю даже при объявлении в непубличном extension, но его свидетели должны удовлетворять требованиям публичного API.
Такое правило поддерживает разделение реализации и публичного контракта. Разработчик может вынести соответствие в отдельный файл или внутреннее расширение, не меняя доступность самого контракта библиотеки.
Иначе доступность API зависела бы от места объявления extension, что усложнило бы модульную компиляцию и оформление протокольных соответствий.
Важно различать доступность соответствия и доступность конкретных членов типа. Клиентский модуль может использовать публичный тип там, где требуется публичный протокол, но не обязан получать прямой доступ к внутренним вспомогательным методам, участвующим в реализации.
Неверное предположение, что внутреннее extension автоматически скрывает соответствие, приводит к ошибкам проектирования API: соответствие считают недоступным и дублируют его или создают ненужные адаптеры.
Доступность протокольного соответствия вычисляется независимо от синтаксического места его объявления. Она ограничена доступностью типа и протокола: внутренний тип не может получить публичное соответствие публичному протоколу, а публичный тип и публичный протокол могут образовать доступное извне соответствие.
При этом реализация требований должна быть совместима с тем уровнем API, на котором используется соответствие. Если реализация требования должна быть частью публичного интерфейса, её нельзя скрыть так, чтобы публичный контракт ссылался на недоступные типы или члены.
Из этого следуют два практических вывода:
Такой подход предотвращает расхождение между видимостью протокольного контракта и возможностью использовать тип в generic-коде другого модуля.
Библиотека предоставляет публичный тип модели и публичный протокол сериализации. Команда выносит соответствие модели протоколу в отдельный внутренний файл, рассчитывая, что клиенты не смогут передавать модель в API, принимающий этот протокол.
Вариант с внутренним extension не решает задачу: при публичных типе и протоколе соответствие может оставаться доступным клиентам. Дублирование протокола или создание отдельного типа-обёртки усложняет API и увеличивает стоимость поддержки.
Рациональное решение — явно определить, должен ли протокол быть частью публичного API. Если нет, его следует сделать непубличным. Если да, соответствие нужно рассматривать как часть публичного контракта независимо от расположения extension и проверить доступность всех используемых в нём типов.
1. Может ли внутренний тип получить публичное соответствие публичному протоколу?
Нет. Публичный API не может раскрывать тип, недоступный клиентскому модулю. Минимальная доступность типа ограничивает доступность его соответствия.
2. Становится ли каждое соответствие публичного типа публичным автоматически?
Нет. Если протокол сам внутренний, клиентский модуль не сможет использовать это соответствие через имя протокола. Доступность определяется совокупностью ограничений, а не только уровнем типа.
3. Можно ли скрыть соответствие, сделав extension внутренним?
Нет, одного уровня доступа extension недостаточно. Он управляет видимостью объявлений внутри расширения, но не служит надёжным механизмом сокрытия протокольного соответствия. Для ограничения API нужно изменить доступность протокола или типа либо разместить реализацию в модуле, недоступном клиенту.