2017-03-01 42 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) 
    } 
}