符合协议并保持私有财产
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了符合协议并保持私有财产相关的知识,希望对你有一定的参考价值。
我需要在一致的类中使用协议属性作为私有。但是编译器拒绝这样做。我该如何实现呢?
protocol ProtocolX: class {
var x: Int { get set }
func performAnyActionOnX()
}
extension ProtocolX {
func performAnyActionOnX() {
x = 5
print(x)
}
}
class A: ProtocolX {
private var x:Int = 7
}
谢谢。
答案
根据@ TheAppMentor评论中所述的原因,没有针对您的问题的确切解决方案。但是,如果您的目的是让您的代码可以理解为人类(而不是欺骗编译器),那么可能会有一些解决方法。
在Swift 4.0中编译。
解决方案1:类似Python的__privacy
快速而简单。此解决方案依赖于同意从_
开始的属性和函数是私有且不应被访问的用户。
protocol ProtocolX: class {
// Public x
var x: Int { get }
// It's private!
var _x: Int { get set }
func performAnyActionOnX()
}
extension ProtocolX {
var x: Int { return _x }
func performAnyActionOnX(){
_x = 5
print(x)
}
}
class A: ProtocolX {
var _x: Int = 7
}
解决方案2:附加的抽象层
建筑上正确。您应该将协议拆分为两部分:私有和公共。
protocol ProtocolX: class {
var x: Int { get }
func performAnyActionOnX()
}
protocol ProtocolXImplementation: class {
var _x: Int { get set }
}
extension ProtocolXImplementation {
var x: Int { return _x }
func performAnyActionOnX(){
_x = 5
print(x)
}
}
class A: ProtocolX, ProtocolXImplementation {
var _x: Int = 7
}
// ... somewhere later ...
// Hide the implementation when use `A`:
let item: ProtocolX = A()
另一答案
正如@TheAppMentor所提到的,从Swift 4开始,似乎没有解决这个问题的确切方法。
但是,有两个近似的解决方案:
1.)
由于Swift中的协议默认具有internal
的访问级别,因此将变量设为internal
。为了使编译器强制执行internal
,请将协议,类及其所有使用者(用户)移动到单独的模块(框架)。
/* internal */ protocol ProtocolX: class {
var x: Any { get set }
func performAnyActionOnX()
}
extension ProtocolX {
func performAnyActionOnX() {}
}
/* internal */ class A: ProtocolX {
internal var x: Any = 0
}
2.)
为协议提供private
的访问级别和变量fileprivate
的访问级别。为了能够访问private
协议,请将协议,类及其所有使用者移动到同一源文件中。
private protocol ProtocolX: class {
var x: Any { get set }
func performAnyActionOnX()
}
extension ProtocolX {
func performAnyActionOnX() {}
}
class A: ProtocolX {
fileprivate var x: Any = 0
}
以上是关于符合协议并保持私有财产的主要内容,如果未能解决你的问题,请参考以下文章