当使用结构代替类来实现更加面向协议的编程方法时,我遇到了一些访问控制难题。
我通过网络接收不同的消息类型,它们的原始形式只是一个字节数组。
所以我从一个协议开始。 请注意rawBytes
仅标记为 { get }
,以便调用者无法直接操作原始字节:
protocol NetworkDataRequest {
var rawBytes: [UInt8] { get }
}
我试图保持线程安全并使用Swift的所有值类型,面向协议的优点,所以我现在使用结构而不是类创建不同的消息类型,并采用协议。
struct FileRequest: NetworkDataRequest {
private(set) var rawBytes: [UInt8]
}
struct ConnectionRequest: NetworkDataRequest {
private(set) var rawBytes: [UInt8]
}
所有不同的消息类型共享前10个字节的类似结构,例如:
因为我使用结构,所以我没有继承权。但我仍然需要一些方法在消息类型之间有类似的行为。好的,我使用协议扩展名:
extension NetworkDataRequest {
var permissionsByte: UInt8 {
get { return bytes[0] }
set { bytes[0] = newValue } //<-- Nope!
}
}
但是哎呀! rawBytes
无法访问:
Cannot assign through subscript: 'rawBytes' is a get-only property
这有什么办法吗?否则我的所有结构都将有很多样板代码(对我来说很糟糕),或者我将不得不打开rawBytes(非常糟糕)
struct FileRequest: NetworkDataRequest {
private(set) var rawBytes: [UInt8]
var permissionsByte: UInt8 {
get { return bytes[0] }
set { bytes[0] = newValue }
}
var connectionTypeByte: UInt8 {
get { return bytes[1] }
set { bytes[1] = newValue }
}
///etc...
}
答案 0 :(得分:1)
这样的事情怎么样?
public protocol NetworkDataRequest {
var rawBytes: [UInt8] { get }
}
private protocol NetworkDataRequestPrivate: NetworkDataRequest {
var rawBytes: [UInt8] { get set }
}
extension NetworkDataRequest {
var permissionsByte: UInt8 {
get { return rawBytes[0] }
}
}
extension NetworkDataRequestPrivate {
var permissionsByte: UInt8 {
get { return (self as NetworkDataRequest).permissionsByte }
set { rawBytes[0] = newValue }
}
}
public struct FileRequest: NetworkDataRequestPrivate {
fileprivate(set) public var rawBytes: [UInt8]
}
public struct ConnectionRequest: NetworkDataRequestPrivate {
fileprivate(set) public var rawBytes: [UInt8]
}
答案 1 :(得分:0)
如果协议和协议扩展名在同一文件中定义,则使用fileprivate
代替private
fileprivate
允许来自同一文件的代码访问它,但在文件之外它是不可访问的。