需求分析:
1)由於一個方法要返回多種可能的類型,因此須要用到泛型。json
// 定義一個 A 對象
public struct A {
init(json: JSON)
}
// 取 A
func getA<T>(type: T.Type) -> T? {
if type == A.self { // 根據不一樣類型,作不一樣解析
return A(json: JSON) as? T
}
return nil
}
複製代碼
完成。
2)可是 1> 調用者傳未定義的類型 T 怎麼辦
2> 可不能夠避免解析後強轉爲 T
3> 解析方法可不能夠統一塊兒來,不作判斷優化
因此,並非任意 T 類型都實現了 init(json: JSON)
方法,咱們應該對 T 作約束,只能傳咱們定義的模型。
考慮到咱們的每一個模型都有相同的方法 init(json: JSON)
,因此此處可用協議對咱們的模型作約束,讓模型遵照此協議,並必須實現 init。ui
優化後以下:url
public protocol Returnable {
init(json: JSON)
}
public struct AModel: Returnable {
public var a: Double = 0
init(json: JSON) {
a = json["aKey"].DoubleValue
}
}
public struct BModle: Returnable {
public var b: Double = 0
init(json: JSON) {
b = json["bKey"].DoubleValue
}
}
........ more custom model types
複製代碼
調用spa
public func getVariousModle<T: Returnable>(type: T.Type)-> Observable<(T)> {
return HTTPClient.rxRequest(url: url, method: .get)
.map { (arg) -> (T) in
let (_, dataJSON) = arg
return T(json: json) // 準守 Returnable 協議的模型都支持 init(json: JSON)
}
}
複製代碼
完成。
雖然實現了根據參數返回不一樣模型,可是,此處必須已知想要的 T.Type 才能傳參,因此可不能夠不傳 type 參數?
未完......code