Swift 协议扩展:无法分配给get only属性
在使用结构代替类来实现更面向协议的编程方法时,我遇到了一个访问控制难题 我通过网络接收不同的消息类型,它们的原始形式只是一个字节数组 所以我从一个协议开始请注意Swift 协议扩展:无法分配给get only属性,swift,protocol-extension,Swift,Protocol Extension,在使用结构代替类来实现更面向协议的编程方法时,我遇到了一个访问控制难题 我通过网络接收不同的消息类型,它们的原始形式只是一个字节数组 所以我从一个协议开始请注意rawBytes如何仅标记为{get},以便调用者无法直接操作原始字节: protocol NetworkDataRequest { var rawBytes: [UInt8] { get } } 我试图做到线程安全,并使用Swift的所有值类型、面向协议的优点,因此我现在使用结构而不是类创建不同的消息类型,并采用协议 str
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个字节中共享类似的结构,例如:
- 字节[0]=权限字节
- 字节[1]=连接类型字节
- 等等
extension NetworkDataRequest {
var permissionsByte: UInt8 {
get { return bytes[0] }
set { bytes[0] = newValue } //<-- Nope!
}
}
这有什么办法吗?否则我所有的结构都会有很多样板代码(对我来说很糟糕),或者我不得不打开rawBytes(非常糟糕)
如果协议和协议扩展在同一文件中定义,则使用
fileprivate
而不是private
fileprivate
允许来自同一文件的代码访问该文件,但在该文件之外无法访问该文件
参考-像这样的东西怎么样
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]
}
它们的原始形式只是一个字节数组。
不,它们不是,它们是数据。使用数据
。有趣!。我看到的唯一问题是,现在我被困在一个单一的源文件中。其中一些请求类型具有与之关联的大型字典,占用了许多代码行。i、 e.当字节[9]=100时表示“你好”,当字节[9]=101时表示“再见”,等等@MH175将在Swift 4中修复private
将扩展对同一源文件中同一模块内扩展名的访问,而不是对同一模块的访问。@MartinR Oops,我记错了。那没关系:p
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...
}
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]
}