Search code examples
swiftencapsulation

Why does Swift allow access of private variables in the same file?


I've just found out that Swift's private access modifier is file level, as stipulated in the docs under "Access Levels":

Private access in Swift differs from private access in most other languages, as it’s scoped to the enclosing source file rather than to the enclosing declaration. This means that a type can access any private entities that are defined in the same source file as itself, but an extension cannot access that type’s private members if it’s defined in a separate source file.

So this means the following code will compile when the types are in the same file:

class FirstType {
    private var privateProperty: String = ""
}

class SecondType {
    private let firstType = FirstType()

    func messWithFirstType() {
        firstType.privateProperty = "👻" // this compiles and works!
    }
}

As far as I can see, this breaks encapsulation completely. On the other hand, it might be nice to have some related types grouped together in the same file for readability, especially if the related types are tiny, like enums.

Private extensions are an exception because they are extending the same type the file is meant to contain. And private extensions do bring some nice things.

Are there any other reason, apart from facilitating private extensions, for the file scope private access modifier to be in Swift?


Solution

  • It isn't clear to me why private was originally implemented with regard to files, but rest assured that the Swift folks know this is not the only possible meaning of private and that it isn't ideal for some purposes, and are working to change it. There's already a proposal on the table, accepted for Swift 3, that will turn the current private into fileprivate and add a new level of private that will be scoped to the type rather than the file. You can expect to see this become part of Swift 3 in the very near future.