Ответ
Оба модификатора ограничивают видимость, но их область действия (scope) разная.
private
- Область действия: Самый строгий уровень. Доступ разрешен только внутри непосредственно окружающего блока объявления (класса, структуры, перечисления) и его расширений (
extension), но только если эти расширения находятся в том же исходном файле. - Цель: Полная инкапсуляция деталей реализации внутри одного типа.
fileprivate
- Область действия: Доступ разрешен для любого кода в пределах того же исходного файла.
- Цель: Разделение реализации между несколькими типами или расширениями в одном файле, скрывая детали от остальной части модуля.
Практический пример:
// File: DataManager.swift
class DataManager {
private var databaseKey = "secret" // Видно только внутри DataManager в ЭТОМ файле
fileprivate var cache = [String: Any]() // Видно во всём файле DataManager.swift
}
// Расширение в ТОМ ЖЕ файле имеет доступ к private
extension DataManager {
func debugPrintKey() {
print(databaseKey) // OK: расширение в том же файле
}
}
// Другой тип в ТОМ ЖЕ файле имеет доступ только к fileprivate
class CacheHelper {
func clearCache(of manager: DataManager) {
// print(manager.databaseKey) // Ошибка: 'databaseKey' is private
manager.cache.removeAll() // OK: 'cache' is fileprivate
}
}
Когда что использовать:
- Используйте
privateпо умолчанию для скрытия внутренних свойств и методов. - Используйте
fileprivate, когда необходимо, чтобы несколько типов в одном файле (например, внутренний хелпер-класс и основной класс) имели доступ к общему состоянию, не раскрывая его за пределы файла.
Ответ 18+ 🔞
Смотри, тут такая хуйня с этими модификаторами, они оба как бы прячут, но масштаб пиздеца у них разный.
private
- Где работает: Самый строгий, блядь. Доступно только внутри того самого блока, где объявил (класс, структура, перечисление) и в его расширениях (
extension), но только если эти расширения в том же файле. - Зачем: Чтобы нахуй спрятать все внутренние кишки реализации внутри одного типа.
fileprivate
- Где работает: Доступно для всего кода в пределах одного исходного файла, ёпта.
- Зачем: Чтобы поделиться какой-то хуйнёй между несколькими типами в одном файле, но скрыть это от всего остального модуля.
Пример, чтобы не быть мудаком:
// Файл: DataManager.swift
class DataManager {
private var databaseKey = "secret" // Видно только внутри DataManager в ЭТОМ файле
fileprivate var cache = [String: Any]() // Видно во всём файле DataManager.swift
}
// Расширение в ЭТОМ ЖЕ файле видит private
extension DataManager {
func debugPrintKey() {
print(databaseKey) // ОК: расширение в том же файле
}
}
// Другой тип в ЭТОМ ЖЕ файле видит только fileprivate
class CacheHelper {
func clearCache(of manager: DataManager) {
// print(manager.databaseKey) // Ошибка: 'databaseKey' is private
manager.cache.removeAll() // ОК: 'cache' is fileprivate
}
}
Так когда что юзать, блядь:
- Бери
privateпо дефолту, чтобы спрятать внутренние свойства и методы — это основа, ебать. - Бери
fileprivate, когда надо, чтобы несколько типов в одном файле (типа внутренний хелпер и главный класс) могли шарить какое-то общее состояние, не вынося сор из избы, то есть из файла.