10

Specifically in regards to member variables, is there a difference between the following in Swift 3? In both cases, Foo is accessible by all code in that same file. Same thing with the implicitly-scoped 'laa' property, which seems to contradict the documentation.

If you define a type’s access level as private or file private, the default access level of its members will also be private or file private.

However, in both cases below, 'laa' is accessible from other classes in the same file implying that it is fileprivate, not private as the docs say the first one should be.

private class Foo
{
    var laa:String
}

fileprivate class Foo
{
    var laa:String
}
Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • 1
    Related: [Distinction between private and fileprivate top-level classes](http://stackoverflow.com/questions/43054774/distinction-between-private-and-fileprivate-top-level-classes) – Hamish Apr 19 '17 at 18:27
  • Thanks for removing the dup! :) – Mark A. Donohoe Apr 19 '17 at 18:28
  • I would simply say the documentation is wrong in this case, or at the very least misleading – the scope in which a `private` type's members are accessible is by default the enclosing scope that defines that type. In the case of being declared at the top level – the file is that scope. – Hamish Apr 19 '17 at 18:35
  • You should put that as an answer, not a comment, so I can close this out as such. – Mark A. Donohoe Apr 19 '17 at 18:56

1 Answers1

12

As said in this Q&A – there's no difference in the access levels between a top-level private and fileprivate declaration. private simply means that it's accessible only in the enclosing scope1, and at the top-level – the file is that scope.

Regarding the documentation comment:

If you define a type’s access level as private or file private, the default access level of its members will also be private or file private.

I would say this is incorrect, or at the very least misleading in the case of private. The scope in which a given type's members are visible is by default the scope that the type declaration itself is visible in (with the exception of access levels higher than internal).

Therefore the scope in which a private type's members are accessible is by default the enclosing scope that defines that type. At the top level, that's the file.

It's probably simpler just to say that type members default to being internal. Being declared in a type with a lower access level than this (such as private or fileprivate) just prevents the members from being visible outside of these access levels (as it makes no sense to refer to a given type's member without being able to see the type itself).


1. Note that in Swift 4, as per SE-0169, extensions of a given type that are declared in the same source file as the type have the same access control scope as the scope of the type declaration. Therefore they can access private members of the type.

Hamish
  • 78,605
  • 19
  • 187
  • 280
  • Very concise and clear answer. Thank you. – migrant Mar 14 '21 at 16:38
  • How unique is it to Swift to treat files as scope? I would have assumed that the files themselves were completely arbitrary and that scope was defined entirely by code. – trndjc Dec 02 '21 at 02:31