What is a good example to differentiate between fileprivate and private in Swift3

旧城冷巷雨未停 提交于 2019-12-17 05:32:31

问题


This article has been helpful in understanding the new access specifiers in Swift 3. It also gives some examples of different usages of fileprivate and private.

My question is - isn't using fileprivate on a function that is going to be used only in this file the same as using private?


回答1:


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:

  1. 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.

  2. 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.




回答2:


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 ]




回答3:


A practical rule of thumb is that you use private for variables, constants, inner structs and classes that are used only inside the declaration of your class / struct. You use fileprivate for things that are used inside of your extensions within the same file as your class/struct but outside of their defining curly braces (ie. their lexical scope).

    class ViewController: UIViewController {
        @IBOutlet var tableView: UITableView!
        //This is not used outside of class Viewcontroller
        private var titleText = "Demo"
        //This gets used in the extension
        fileprivate var list = [String]()
        override func viewDidLoad() {
            navigationItem.title = titleText
        }
    }

    extension ViewController: UITableViewDataSource {
        func numberOfSections(in tableView: UITableView) -> Int {
            return list.count
        }
    }



回答4:


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**

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

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.




回答5:


Although @MartinR's and @StephenChen's answer are perfect, Swift 4 changes things a little bit.

Private is now considered as private to a class in which it is declared and also to its extensions.

FilePrivate is considered to be private in that file be it a class in which the variable is defined, it's extension, or any other classes defined in that same file.




回答6:


In the following example, language constructs modified by private and fileprivate seem to behave identically:

fileprivate func fact(_ n: Int) -> Int {
    if (n == 0) {
        return 1
    } else {
        return n * fact(n - 1)
    }
}

private func gauss(_ n: Int) -> Int {
    if (n == 0) {
        return 0
    } else {
        return n + gauss(n - 1)
    }
}

print(fact(0))
print(fact(5))
print(fact(3))

print(gauss(10))
print(gauss(9))

This is according to intuition, I guess. But, is there any exception?

Kindest regards.




回答7:


This is the explanation for swift 4. For swift 3, the difference is the private. swift 3 private cannot be accessed by its extension, only Class A itself can access.

After swift 4, fileprivate becomes a bit redundant, because person normally will not define the subclass in the same file. Private should be enough for most cases.




回答8:


filePrivate - access controll level is within the file.

case 1: If we create extension with in same class file and try to access fileprivate function or fileprivate property in its extension - access allowed
case 2: If we create a extension of class in new file - And now try to access fileprivate function or fileprivate property - access not allowed

private - access control level is with in lexical scope

case 1: If property or function is declared as private in class - then scope is by default the class. case 2: if private instance is declared with in function body - then scope of instance is limited to function body.




回答9:


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 file
aObj.result //Private varaible will not be accessible outside its definition except extensions

extension 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.




回答10:


class Privacy {

    fileprivate(set) var pu:Int {
        get {
            return self.pr
        }
        set {
            self.pr = newValue
        }
    }
    private var pr:Int = 0
    fileprivate var fp:Int = 0


    func ex() {
        print("\(self.pu) == \(self.pr) and not \(self.fp)")
    }
}


extension Privacy {

    func ex2() {
        self.pu = 5
        self.ex()
    }

}

I like this because it is super simple for ivars.

Try changing fileprivate to private (and vice versa) and see what happens on compile...



来源:https://stackoverflow.com/questions/39027250/what-is-a-good-example-to-differentiate-between-fileprivate-and-private-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!