2017-03-01 41 views
2

我一直在瀏覽swift文檔,並通過封裝的一些示例進行研究,並且不確定我看到的行爲。我已經在堆棧中尋找類似的問題,查看文檔並查看一些教程(請參閱下面的鏈接),雖然這是一個小問題無法找到答案(可能是因爲Swift已更改?)Swift 3從擴展中訪問結構中的私有屬性

創建代表隊列一個簡單的結構:

struct Queue<Element> { 
private var elements = [Element]() 
mutating func enqueue(newElement: Element) { 
    elements.append(newElement) 
} 

mutating func dequeue() -> Element? { 
    guard !elements.isEmpty else { 
     return nil 
    } 
    return elements.remove(at: 0) 
} 
} 

後來被擴展:

extension Queue { 
func peek() -> Element? { 
    return elements.first 
} 
} 

,但當然元素是不可訪問,由於私人保護級別。 它通過改變元素訪問fileprivate的工作 - 但爲什麼?

我的理解是擴展是封閉類型的一部分,並期待似乎是用於這樣的工作方式https://www.andrewcbancroft.com/2015/04/22/3-nuances-of-swift-extensions/

所以是我的知名度理解錯了,或者已經斯威夫特改變了網絡上?

+0

應該刪除參數名稱,如'newElement',不任何有意義的信息添加到呼叫現場 – Alexander

+0

而且,你可能想要實現一個隊列作爲循環緩衝區。從陣列開始移除代價很高。 – Alexander

+0

好吧,雖然這只是一個小例子來說明問題。 – stevenpcurtis

回答

2

Swift's book

私接限制使用的實體到封閉聲明。當這些細節僅在單個聲明中使用時,使用私有訪問來隱藏特定功能的實現細節。

因此,一個private變量只能在其定義的花括號集內進行訪問。 Swift的訪問控制從來沒有像C++ ,Java或C#那樣。

+0

好的謝謝。所以擴展不被認爲是原始聲明的一部分。這是否改變了Swift的不同迭代? – stevenpcurtis

+1

Swift 2中的'private'行爲與Swift 3中的'fileprivate'行爲相同。如果您的擴展名位於不同的文件中,它仍然允許訪問該變量。 –

1

隨着Swift 4的發佈,這已經發生了變化。您可以參考此文檔下面 Private Member in Extension

例子與斯威夫特4

protocol SomeProtocol { 
    func doSomething() 
} 
struct SomeStruct { 
    private var privateVariable = 12 
} 
extension SomeStruct: SomeProtocol { 
    func doSomething() { 
     print(privateVariable) 
    } 
}