What is a good example to differentiate between fileprivate and private in Swift3
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
theclass 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.
Difference between fileprivate and private extension?
The difference only crops up when we are talking about type members. private
will restrict access to other methods within the same type definition, while fileprivate
things are accessible by anything that lives in the same .swift
file.
For things that live at the top level (outside of a type definition), private
and fileprivate
do exactly the same thing. So when you write
fileprivate extension Foo
{
var aa: Int
{
return aaa + 10
}
}
private extension Foo
{
var aaa: Int
{
return 20
}
}
You really wrote
fileprivate extension Foo
{
var aa: Int
{
return aaa + 10
}
}
fileprivate extension Foo
{
var aaa: Int
{
return 20
}
}
Ultimately, the two extensions on the same protocol get resolved by the compiler into a single extension.
fileprivate extension Foo
{
var aa: Int
{
return aaa + 10
}
var aaa: Int
{
return 20
}
}
If you think think having two keywords like this is stupid, some Swift architects agree with you. I believe some style guides recommend you only bother using the public
and private
access modifiers (as well as the internal
modifier, but that one is by default) because, in general, restricting things on a per-file basis, as opposed to a per-module or per-type basis is not particularly useful.
If you must use the fileprivate
modifier, then never use the private
modifier outside of a type scope. It’s confusing (since the private
in that context “really” means fileprivate
) and makes your code harder to read.
What is the difference between private and fileprivate in Swift 4
File Private
File-private access restricts the use of an entity to its own defining source file. Use file-private access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.
Syntax: fileprivate <var type> <variable name>
Example: fileprivate class SomeFilePrivateClass {}
Private
Private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file. Use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.
Syntax: private <var type> <variable name>
Example: private class SomePrivateClass {}
Here is more detail about all access levels: Swift - Access Levels
Answer to your question:
(In Swift 3, private variables in a class are not visible in its extensions in the same file. For that, fileprivate had to be used.)
Yes, in Swift 4.0, Private is now accessible in extension but within same file. If you declare/define extension in other file, then your private variable will not be accessible to your extension
Look at this images:
File: ViewController.swift
Here extension and view controller both are in same file, hence private variable testPrivateAccessLevel
is accessible in extension
File: TestFile.swift
Here extension and view controller both are in different files, hence private variable testPrivateAccessLevel
is not accessible in extension.
Here class ViewController2
is a subclass of ViewController
and both are in same file. Here private variable testPrivateAccessLevel
is not accessible in Subclass but fileprivate is accessible in subclass.
Distinction between private and fileprivate top-level classes
There is no difference in your case. The only time that fileprivate
differs from private
is inside a class, struct, or protocol.
What is the significance of filePrivate now in Swift 4?
private
limits access to that class within that file. fileprivate
limits access to that file.
Imagine these are all in the same file:
class Foo {
private var x = 0
fileprivate var y = 0
}
extension Foo {
func bar() {
// can access both x and y
}
}
class Baz {
func qux() {
let foo = Foo()
// can access foo.y, but not foo.x
}
}
Swift: is there any functional difference between private static let (in a class definition) and fileprivate let (no owner)
The functional difference is minor: Your fileprivate
(which could be private
) global is accessible to all types defined within that file, whereas the former is limited to that one particular SomeClass
.
The “private global” arguably requires non-local reasoning (i.e., you might have to scan through the whole file to see which types are there and might have access to it). On the other hand, the “private static property” makes the intent more clear at glance. As a result, many would favor this “private static property” approach.
For what it is worth, there is a hybrid approach:
class SomeClass {
var possibleValues: [String] {
return Self.someValues
}
}
private extension SomeClass {
private static let someValues: [String] = [
"mrah!",
"blah",
"shmah!"
]
}
It keeps the core type definition very clean, but keeps the namespace for the static
constant. Sometimes it is nice to put various subtypes, methods, and statics in extensions within the same file. It can make it easy to grok the code, facilitates code folding, etc.
What does 'fileprivate' keyword means in Swift?
fileprivate
is one of the new Swift 3 access modifiers that replaces private
in its meaning. fileprivate
defines an entity (class, extension, property, ...) as private to everybody outside the source file it is declared in, but accessible to all entities in that source file.
private
restricts the entity in the direct enclosing scope.
Swift 3: The difference between Public and Internal access modifiers?
Your diagram is just incorrect.
Public members of A.swift
and B.swift
are available to C.swift
and D.swift
. The only restriction is that classes can't be subclassed (they would need to be open
.
Related Topics
How Does One Generate a Random Number in Swift
Passing an Array to a Function With Variable Number of Args in Swift
Sort Dictionary by Values in Swift
Accessing an Enumeration Association Value in Swift
Accessing Code in Swift 3 Error
Swift: How to Use Preprocessor Flags (Like '#If Debug') to Implement API Keys
== Overload for Custom Class Is Not Always Called
Sheet Inside Foreach Doesn't Loop Over Items Swiftui
How to Create a Multi-Line Text Inside a Scrollview in Swiftui
Swiftui Hstack With Wrap and Dynamic Height
How to Generate a Random Number in Swift Without Repeating the Previous Random Number
How to Compare Enum With Associated Values by Ignoring Its Associated Value in Swift
How to Unwrap an Optional Value from Any Type