Какие существуют модификаторы доступа в Swift
Что проверяют
Знаете ли вы пять уровней и понимаете ли разницу между двумя самыми открытыми.
Как отвечать
Уровней пять, от самого закрытого:
private: внутри объявляющей области и расширений в том же файле. Последнее важно: до Swift 4 расширения не имели доступа, и приходилось использовать более широкий уровень;fileprivate: внутри всего файла;internal: внутри модуля. Значение по умолчанию, поэтому большая часть кода приложения именно такая;public: доступен из других модулей, но наследовать класс и переопределять методы нельзя;open: доступен и открыт для наследования и переопределения снаружи модуля.
Разница между двумя последними существует только для библиотек и есть особенность именно Swift. Автор библиотеки решает не только «видно ли снаружи», но и «можно ли на этом строить». Это защищает от того, что чужое переопределение сломает внутренние инварианты при обновлении версии.
С версии 5.9 добавился уровень package: видимость внутри одного пакета из нескольких модулей. Он закрыл дыру между модулем и полной публичностью в проектах, разбитых на много модулей.
Полезные детали:
- видимость сеттера задаётся отдельно: запись
private(set) var itemsдаёт чтение снаружи и запись только изнутри. Очень частый и удобный приём; - нельзя сделать член более открытым, чем его тип. Публичная функция не может возвращать внутренний тип, компилятор это запретит;
- у расширения можно задать уровень по умолчанию для всех его членов.
Практика: оставлять уровень по умолчанию внутри приложения и явно продумывать видимость на границах модулей.
Где спотыкаются
Не различают доступность и открытость для наследования.
Считают закрытый уровень ограниченным одним типом, забывая про расширения в файле.
Пишут публичность везде по привычке из других языков.
Не знают про раздельную видимость сеттера.