1

在使用结构代替类来实现更面向协议的编程方法时,我遇到了一些访问控制难题。

我通过网络接收不同类型的消息,它们的原始形式只是一个字节数组。

所以我从一个协议开始。请注意,如何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] = 连接类型字节
  • ETC...

由于我使用的是结构,所以我没有继承。但是我仍然需要一些方法来在消息类型之间有类似的行为。好的,所以我使用协议扩展:

 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...

}
4

2 回答 2

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]
}
于 2017-05-01T04:30:33.480 回答
0

如果协议和协议扩展定义在同一个文件中,则fileprivate使用private

fileprivate允许来自同一文件的代码访问它,但在文件之外它是不可访问的。

参考 - https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html

于 2017-05-01T04:13:35.863 回答