В чем разница между модификаторами доступа fileprivate и private в Swift?

Ответ

Оба модификатора ограничивают видимость, но их область действия (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, когда надо, чтобы несколько типов в одном файле (типа внутренний хелпер и главный класс) могли шарить какое-то общее состояние, не вынося сор из избы, то есть из файла.