2017-05-01 33 views
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] = permissionsByte
  • 字節[1] = connectionTypeByte
  • 等...

由於我使用結構我沒有繼承。但是我仍然需要一些方法來在消息類型之間有類似的行爲。 OK,所以我使用協議擴展:

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

} 
+1

'它們的原始形式只是一個字節數組.'不,它們不是,它們是數據。使用'數據'。 – Alexander

回答

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] 
} 
+0

有趣!我看到的唯一問題是,現在我被困在一個單一的源文件中。這些請求類型中有一些與他們相關的巨大字典佔用了許多代碼行。即當byte [9] = 100時,它是「Hello」,當byte [9] = 101時,它是「Goodbye」等。 – MH175

+0

@ MH175這將在Swift 4中修復。private將擴展同一模塊中的擴展https://github.com/apple/swift-evolution/blob/master/propsals/0169-improve-interaction-between-private-declarations-and-extensions.md – Alexander

+0

在同一個源文件中,不是相同的模塊。 –

相關問題