В Swift уровни доступа (private, fileprivate, internal, public, open) влияют не только на классы, структуры и их свойства, но и на вложенные (nested) типы. Вложенный тип по умолчанию наследует уровень доступа своего окружающего типа, если не указано иное явное ограничение.
Главные нюансы:
internal, вложенный тип не может быть более открытым, чем внешний, но может быть более «закрытым» (например, внешний — public, вложенный — private).internal, не будут видны из других модулей.Пример:
public class A { public struct B { fileprivate func foo() {} } }
В этом примере A и B публичные, но метод foo() — файл-приватен.
Вопрос: "Может ли вложенный тип иметь уровень доступа выше, чем окружающий его тип?"
Ответ: Нет, уровень доступа вложенного типа не может превышать уровень доступа его окружающего типа. Если попытаться объявить вложенный тип с более высоким уровнем доступа, компилятор выдаст ошибку.
Пример ошибки:
internal struct MyStruct { public enum MyEnum { ... } // Ошибка: public не может быть внутри internal }
История 1
В общем фреймворке уровни доступа вложенных структур не были синхронизированы с внешними типами. В релизной версии это привело к невозможности использовать внутренние enum в клиентском приложении, и потребовалось срочное изменение интерфейса.
История 2
В большом проекте внутренний сервисный объект имел вложенный класс со статусами, объявленный как internal. После появления нового модуля, зависевшего от этого класса, интеграция оказалась невозможной без повышения уровня доступа и полной перекомпиляции SDK.
История 3
В сложной библиотеке часть вложенных структур декларировалась как public, а сам контейнер — internal. Во время миграции на новую версию возникли критические ошибки: публичные типы не компилировались во внешнем контексте, что затородило обновление нескольких команд.