這個article有助於理解Swift 3
中的新訪問說明符。它還給出了fileprivate
和private
不同用法的一些例子。在swift3中區分fileprivate和private的一個很好的例子
我的問題是 - 沒有使用fileprivate
函數,這個函數只會在這個文件中使用,與使用private
相同?
這個article有助於理解Swift 3
中的新訪問說明符。它還給出了fileprivate
和private
不同用法的一些例子。在swift3中區分fileprivate和private的一個很好的例子
我的問題是 - 沒有使用fileprivate
函數,這個函數只會在這個文件中使用,與使用private
相同?
fileprivate
現在是什麼private
曾經在以前 迅速發佈:從 訪問同一個源文件。標註爲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()
私人foo
方法僅 的class A { ... }
定義的範圍內是可訪問的。它甚至不能從 擴展到該類型(在Swift 3中,請參閱下面的第二個註釋,以瞭解Swift 4中 的變化)。
文件私人bar
方法可從同一個源文件訪問。
注:
SE-0159 – Fix Private Access Levels建議恢復到斯威夫特4雨燕2個語義迅速進化郵件列表上一個漫長而有爭議的討論後建議,提案rejected。
提案SE-0169 – Improve Interaction Between private Declarations and Extensions建議,使同類型的 擴展訪問的類型的內部private
聲明如果擴展在相同的源文件中定義。 這個建議被採納和實施斯威夫特4
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()
}
}
我喜歡這個,因爲它是高德超級簡單。
嘗試改變fileprivate私人(反之亦然),看看在編譯會發生什麼......
根據經驗,實際的規則是,你使用私有變量,常量,即僅用於內部結構和類在你的類/結構的聲明中。你可以在你的擴展中使用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
}
}
在下面的例子上,通過private
和fileprivate
修改語言結構似乎表現相同:
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))
這是根據直覺,我猜。但是,有沒有例外?
最好的問候。
雖然@ MartinR's和@ StephenChen的回答都很完美,Swift 4改變了一些事情。
私人現在被認爲是私有的它宣佈它的類和它的擴展。
FilePrivate在該文件中被認爲是私有的,無論是定義該變量的類,擴展名還是定義在該文件中的任何其他類。
在Swift 4.0中,Private現在可以在擴展中訪問,但在同一個文件中。如果你聲明/定義在其他文件擴展名,那麼你的私有變量不會對您的擴展訪問**
文件私人
文件,私接限制使用的實體自身的定義源文件。當在整個文件中使用這些詳細信息時,使用文件私有訪問來隱藏特定功能塊的實現細節。
語法:fileprivate <var type> <variable name>
實施例:fileprivate class SomeFilePrivateClass {}
私人
私人接入限制使用的實體到封閉聲明的,並且是在相同的該聲明的擴展文件。當這些細節僅在單個聲明中使用時,使用私有訪問來隱藏特定功能的實現細節。
語法:private <var type> <variable name>
例子:private class SomePrivateClass {}
這是所有訪問級別的更多細節:Swift - Access Levels
看看這個圖片:
文件: ViewController.swift
這裏的擴展和視圖控制器都是相同的文件,因此私有變量testPrivateAccessLevel
是擴展訪問
文件: TestFile.swift
這裏延伸和視圖控制器都是在不同的文件,因此私有變量testPrivateAccessLevel
是不是在擴展訪問。
下面類ViewController2
是ViewController
一個子類,都是在同一個文件中。這裏私有變量testPrivateAccessLevel
不能在Subclass中訪問,但fileprivate可以在子類中訪問。
filePrivate - 訪問控制研究水平是在文件中。
情況1:如果我們創建的擴展,在同一類文件,並嘗試訪問fileprivate功能或fileprivate財產及其延伸 - 允許訪問
情況下2:如果我們創建新的文件擴展類的 - 現在嘗試訪問fileprivate功能或fileprivate財產 - 不允許訪問
私人 - 訪問控制水平與詞彙範圍
情況1:如果屬性或函數在類中聲明爲私有 - 那麼範圍默認爲類。 案例2:如果私有實例是在函數體中聲明的 - 那麼實例的作用域限於函數體。
如果您將代碼從Swift 2自動轉換爲3,則Xcode會將'private'變成'fileprivate'。但是,如果你有奢侈的手工操作,你可以通過'private'作爲'private'來獲益,如果它編譯的話,一切都很好。 –