What is a good example to differentiate between fileprivate and private in Swift3
fileprivate
is now what private
used to be in earlierSwift releases: accessible fromthe 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 levela.bar()
The private
foo
method is accessible only within the scope of theclass A { ... }
definition. It is not even accessible froman 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 typeif the extension is defined in the same source file.This proposal was accepted and implemented in Swift 4.
I just draw a diagram about private, fileprivate, open and public
Hope it can quickly help you , for text description please refer to Martin R 's answer
[ Update Swift 4, 5 ]
Updated for Swift 5
Private vs FilePrivate
For better clarity paste the code snippet in Playground
class Sum1 { let a: Int! let b: Int! private var result: Int? fileprivate var resultt: Int? init(a : Int, b: Int) { self.a = a self.b = b } func sum(){ result = a + b print(result as! Int) }}let aObj = Sum1.init(a: 10, b: 20)aObj.sum()aObj.resultt //File Private Accessible as inside same swift fileaObj.result //Private varaible will not be accessible outside its definition except extensionsextension Sum1{ func testing() { // Both private and fileprivate accessible in extensions print(result) print(resultt) }}//If SUM2 class is created in same file as Sum1 ---class Sum2{ func test(){ let aSum1 = Sum1.init(a: 2, b: 2) // Only file private accessible aSum1.resultt }}
Note: Outside of Swift file both private and fileprivate are not accessible.