Difference between fileprivate and private extension?
Asked Answered
H

3

17

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.

Hisakohisbe answered 7/4, 2017 at 21:17 Comment(3)
Hmm... I wonder if it's because the scope of the extension IS the file? If you declared the vars as fileprivate and private instead of the extension then this wouldn't work.Decrepitude
@Decrepitude You are right, if add access modifier to variables, this will not work. Probably, Apple did it, because private extension will not make any sense, i mean everything declared in private extension will be visible only there.Hisakohisbe
Related: #39740313, #43055274.Lentiginous
C
20

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.

Ceramic answered 7/4, 2017 at 21:51 Comment(2)
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?Tussah
@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.Ceramic
C
5

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

Chlorobenzene answered 6/10, 2017 at 6:32 Comment(0)
R
-1

Private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file.

Private extension and filePrivate extension are acting almost the same on the same file.

// Fruite.Swift

struct Fruite {
    let name: String
}

// FruiteTests.Swift

func testSomeThing() {
    let fruite = Fruite()
    let privateDate = fruite.expiryDate_Private // ✅
    let filePrivateDate = fruite.expiryDate_filePrivate // ✅
    
    // both are accessible
}
private extension Fruite {
    var expiryDate_Private : Date {
        return Date()
    }
}

fileprivate extension Fruite {
    var expiryDate_filePrivate: Date {
        return Date()
    }
}
Rollie answered 14/10, 2022 at 10:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.