再說 Swift namespace
之前寫過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{ publicfunc 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{ publicvar 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的本質是二次封裝