Difference between fileprivate and private extension?

11,577

Solution 1

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.

Solution 2

With Swift 4.0, scope of private and fileprivate is extended.
Private is now accessible within same file, outside actual class/extension. If you declare/define your extension in other file, then your private variable will not be accessible at that time fileprivate will work


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

Share:
11,577

Related videos on Youtube

Bohdan Savych
Author by

Bohdan Savych

Just an average guy

Updated on June 04, 2022

Comments

  • Bohdan Savych
    Bohdan Savych almost 2 years

    Swift 3.0

    I know that fileprivate access level modifier limited using of function/property to source file where it was declared and private - limited to lexical scope where was declared. But it seems that this rule not apply for extensions. E.G. this code is valid:

    class Foo {
    }
    
    fileprivate extension Foo {
        var aa: Int {
            return aaa + 10
        }
    }
    
    private extension Foo {
        var aaa: Int {
            return 20
        }
    }
    

    Can someone help me figured out difference between them? Thanks.

    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.

    fileprivate is accessible within same file.

  • mfaani
    mfaani about 7 years
    Not sure I understand what you mean by: "The difference only crops up when we are talking about type members". Additionally not sure how you addressed the actual question, didn't you show a different scenario?
  • taylor swift
    taylor swift about 7 years
    @Honey An extension is not a type member, it is declared at the top level. That is why the private modifier is really a fileprivate modifier spelled differently.