fileprivate
is now what private
used to be in earlier
Swift releases: accessible from
the same source file. A declaration marked as private
can now only be accessed within the lexical scope it is declared in.
So private
is more restrictive than fileprivate
.
As of Swift 4, private declarations inside a type are accessible to extensions of the same type if the extension is defined in the same source file.
Example (all in one source file):
class A {
private func foo() {}
fileprivate func bar() {}
func baz() {
foo()
bar()
}
}
extension A {
func test() {
foo() // Swift 3: error: use of unresolved identifier 'foo'
// Swift 4: no error because extension is in same source file
bar()
}
}
let a = A()
a.foo() // error: 'foo' is inaccessible due to 'private' protection level
a.bar()
The private foo
method is accessible only within the scope of
the class A { ... }
definition. It is not even accessible from
an extension to the type (in Swift 3, see the second note below for
changes in Swift 4).
The file-private bar
method is accessible from the same source file.
Notes:
The proposal SE-0159 – Fix Private Access Levels suggested to revert to the Swift 2 semantics in Swift 4. After a lengthy and controversial discussion on the swift-evolution mailing list, the proposal was rejected.
The proposal SE-0169 – Improve Interaction Between private Declarations and Extensions suggests to make private
declarations inside a type accessible to extensions of the same type
if the extension is defined in the same source file.
This proposal was accepted and implemented in Swift 4.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…