在Swift3中区分fileprivate和private之间有什么好的例子

Nik*_*a P 134 private access-control access-specifier swift swift3

文章已在了解新的访问说明很有帮助Swift 3.它也给出了不同用途的一些例子fileprivateprivate.

我的问题是 - 是不是fileprivate在一个仅在此文件中使用的函数上使用与使用相同private

Mar*_*n R 272

fileprivate现在是private以前Swift版本中的版本:可以从同一个源文件访问.标记为private现在的声明现在只能在它声明的词法范围内访问.因此private比限制更严格fileprivate.

Swift 4开始,如果扩展名在同一源文件中定义,则类型内的私有声明可以被相同类型的扩展访问.

示例(所有在一个源文件中):

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()
Run Code Online (Sandbox Code Playgroud)
  • 私有foo方法只能在class A { ... }定义的范围内访问.它甚至无法从类型的扩展访问(在Swift 3中,请参阅下面的第二个注释,了解Swift 4中的更改).

  • bar可以从同一源文件访问file-private 方法.

笔记:

  1. 提议SE-0159 - 修复私有访问级别建议恢复Swift 4中的Swift 2语义.经过对swift-evolution邮件列表的冗长和有争议的讨论,该提案被拒绝.

  2. 提议SE-0169 - 改进私有声明和扩展之间的交互建议private 如果扩展在同一源文件中定义,则在相同类型的扩展可访问的类型内进行声明. 该提案在Swift 4中被接受并实施.

  • 如果你将代码自动从Swift 2转换为3,Xcode会将`private`变成`fileprivate`.但是,如果你有手工制作的奢侈品,你可以经常将"私人"作为"私人"而受益......如果它编译,那么一切都很好. (2认同)

Ste*_*hen 77

我只是绘制一个关于private,fileprivate,openpublic的图表

希望它可以快速帮助你,对于文字描述请参考Martin R的回答

[更新Swift 4]

在此输入图像描述

  • 注意,`fileprivate`没有链接到扩展名但是链接到文件(在另一个文件中写一个A类扩展名不允许使用`fileprivate`成员) (9认同)

Arp*_*ain 7

为 Swift 5 更新

私人文件私人

为了更清晰,将代码片段粘贴到 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

    }
}
Run Code Online (Sandbox Code Playgroud)

注意:在 Swift 文件之外,private 和 fileprivate 都不可访问。


Jos*_*ann 6

一个实际的经验法则是对变量,常量,内部结构和仅在类/结构声明中使用的类使用private.您可以将fileprivate用于与您的类/结构相同的文件中的扩展内部使用的内容,但在其定义的花括号之外(即它们的词法范围).

    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
        }
    }
Run Code Online (Sandbox Code Playgroud)


Kru*_*nal 6

在Swift 4.0中,现在可以在扩展名中访问Private,但可以在同一文件中访问。如果您在其他文件中声明/定义扩展名,则扩展名将无法访问您的私有变量**

文件专用
文件专用访问将实体的使用限制为自己定义的源文件。当在整个文件中使用特定功能的实现细节时,使用文件专用访问权限可以隐藏这些细节。
语法: fileprivate <var type> <variable name>
示例: fileprivate class SomeFilePrivateClass {}


私有
私有访问将实体的使用限制为封闭的声明以及同一文件中该声明的扩展名。当仅在单个声明中使用特定细节的实现细节时,使用私有访问权限可以隐藏这些细节。
语法: private <var type> <variable name>
示例: private class SomePrivateClass {}


以下是有关所有访问级别的更多详细信息:Swift-访问级别

看这张图:
File: ViewController.swift
这里扩展名和视图控制器都在同一个文件中,因此私有变量testPrivateAccessLevel可以在扩展名中访问

在此处输入图片说明


文件: TestFile.swift
这里扩展名和视图控制器都在不同的文件中,因此私有变量testPrivateAccessLevel在扩展名中不可访问。

在此处输入图片说明

在此处输入图片说明


这里的类ViewController2是的子类,ViewController并且都在同一个文件中。在这里,私有变量testPrivateAccessLevel在子类中不可访问,但fileprivate在子类中可访问。

在此处输入图片说明


Nik*_*a P 5

尽管@MartinR和@StephenChen的答案很完美,但是Swift 4还是有所改变。

私人现在被认为是私人在其声明也为其扩展一个类。

FilePrivate被认为是该文件中的私有文件,无论是在其中定义变量的类,其扩展名,还是在同一文件中定义的任何其他类。