再說swift namespace

如夢一般發表於2019-02-27

之前寫過namespace的問題不過後續都是沒怎麼使用,時下rx,snp…大家都應經不再陌生,也是比較常見的,今天我們結合struct 泛型 class一起看個綜合的例項
通常我們使用名稱空間都是基於一個具體的例項進行的二次封裝(大家公認的)而封裝的載體通常是struct,然後對struct進行extension
背景:
最經在搞protocol buffer來進行資料壓縮,減輕網路流量,於是有了今天的文章

結構定義
在vapor中我們想簡單的返回pb資料不是那麼簡答,因此對返回資料進行了一個包裝

1 返回資料格式

public struct PB<T> : Content where T: Message{
    var value: Data
    init(_ data: T) throws {
        self.value = try data.serializedData()
    }
}
複製程式碼

2 request

extension Request{
   public   func makePB<T>(value: T) throws -> EventLoopFuture<PB<T>> where T: Message{
        let result = self.eventLoop.newPromise(PB<T>.self)
        
        let pb = try PB.init(value)
        
        result.succeed(result: pb)
        
        return result.futureResult
    }
}
複製程式碼

有定義看到返回的是個基於Message的泛型struct,我們暫時放置於此,後續使用

namespace包裝
1 格式定義

class PBBase<Base,  T> where T: Message{
    let base: PB<T>
    init(_ base: Base) {
        self.base = base as! PB<T>
    }
}
複製程式碼

2 協議定義

protocol PBProtocol {
    associatedtype PBType
    associatedtype T: Message
    var pb:PBType{get}
}

extension PBProtocol{
  public  var pb:PBBase<Self, T>{
        return PBBase.init(self)
    }
}
複製程式碼

完成

extension PB : PBProtocol where T: Message{}
複製程式碼

使用

func testPBBase(){
        XCTAssert(pb?.pb.entry != nil, "測試失敗")
        XCTAssert(pb?.pb.textFormatString() == bookInfo?.textFormatString(), "測試失敗")
        XCTAssert(pb?.pb.textString == pb?.textString, "測試失敗")
    }
複製程式碼

我們再來回顧一下整個過程使用了什麼
1 使用 where限定了PBProtocol的使用範圍

2 protocol中associatedtype的綜合使用

2.1 可以定義多個

2.2 可以定義一個具體的型別,也可定義個模糊的型別
複製程式碼

3 nameapce的本質是二次封裝

Github例項連結

相關文章