Search code examples
swiftclass-visibility

Swift access control on computed properties: why does this work?


I seem to be misunderstanding something about access control modifiers in Swift. Here is my code from a playground:

class Something {
    private (set) var name :String {
    get { return "" }
    set {}
    }
}
var thing = Something();
thing.name = "";

My intuition and experience from other languages tells me that there should be a compiler error on the last line.

The book I'm learning from however states that private means the member being modified is only accessible from the same source file.

Am I safe to assume this scenario would generally be an error in most projects, and this is only because I'm running this code in a playground?

Is the statement that private members can only be accessed from the same source file totally accurate?


Solution

  • This rule is valid for all versions of Swift 2. It is valid for your example as well, and worked because your setter code is in the same file (if I understand your example correctly) in which the setter was invoked.

    The top-level assignment expression thing.name = ""; was allowed because it is running in a playground. Outside playgrounds, this particular top-level assignment would be illegal in most cases (there are exceptions!).


    Bonus explanation of what constitutes as "top-level code" and where it is applicable; from the official Swift blog here:

    However, top-level code is not allowed in most of your Swift source files. For clarity, any executable statement not written within a function body, within a class, or otherwise encapsulated is considered top-level. We have this rule because if top-level code were allowed in all your files, it would be hard to determine where to start the program.

    ...

    You’ll notice that earlier we said top-level code isn’t allowed in most of your app’s source files. The exception is a special file named “main.swift”, which behaves much like a playground file, but is built with your app’s source code. The “main.swift” file can contain top-level code, and the order-dependent rules apply as well. In effect, the first line of code to run in “main.swift” is implicitly defined as the main entrypoint for the program. This allows the minimal Swift program to be a single line — as long as that line is in “main.swift”.