我試圖解碼一個符合自定義協議的專案陣列logicBlock。
struct MyModel。Codable {
var var1: String[/span].
var var2: Int var2:
var logicBlocks: [LogicBlock]
}
我看了這個問題,它問的是如何解碼一個陣列的專案,然而我有一個協議,它包含一個像這樣的列舉:
enum LogicBlockTypeID。Int, Codable {
case a = 500
case b =501
case c = 502
}
protocol LogicBlock: Codable {
var typeID: LogicBlockTypeID { get }
}
和結構實作LogicBlock,像這樣:
struct Struct1: LogicBlock {
var someVar = 32
var typeID = .a
}
struct Struct2: LogicBlock {
var someString = "hello">
var typeID = .b
}
struct Struct2。LogicBlock {
var typeID = .c
}
我試圖通過使用init(from decoder: Decoder)
MyModel進行解碼。
var codeContainer = try values.nestedUnkeyedContainer(forKey: .code)
var parsedCode = [LogicBlock]()
enum codingKeys。String, CodingKey {
.../span>
case .logicBlocks
}
init(from decoder: Decoder) {
.../span>
var codeContainer = try values.nestedUnkeyedContainer(forKey: .code)
var parsedCode = [LogicBlock]()
while !codeContainer.isAtEnd {
let nestedDecoder = try codeContainer.superDecoder()
let block = try Program.DecodeLogicBlock(from: nestedDecoder)
parsedCode.append(block)
}
}
private static func decodeLogicBlock(from decoder: Decoder) throws -> LogicBlock {
let values = try decoder.container(keyedBy: LogicBlockTypeID.self)
//Something to distinguinguish what TYPE we have。
return ...
我們如何能夠知道我們在這里解碼的物件的型別?
uj5u.com熱心網友回復:
你可以實作一個具體的型別,即AnyLogicBlock,它將暴露兩個變數let typeID: LogicBlockTypeID和let wrapped: LogicBlock
下面是一個簡化的例子:
enum TypeID。String, Codable {
case a, b
}
protocol MyType {
var type。TypeID { get }
}
struct MyConreteTypeA: MyType {
var type。TYPEID
var someVar: Int
}
struct MyConreteTypeB: MyType {
var type。TYPEID
var someString: String
}
struct AnyType: MyType, Decodable {
private enum CodingKeys: String, CodingKey {
case type, someVar, someString
}
let type。typeID
let wrapped: MyType
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
type = try container.decode(TypeID.self, forKey: .type)
switch type {
case .a:
包裝好的 = MyConreteTypeA(type: 型別, someVar: try container.decode(Int.self, forKey: .someVar)
case .b:
包裹= MyConreteTypeB(type: 型別, someString: try container.decode(String.self, forKey: . someString))
}
}
}
var json = #" "
[
{ "型別": "a", "someVar": 1 },
{ "型別": "b", "someString": "測驗" }
]
""#
let result = try! JSONDecoder(). decode([AnyType].self, from: json.data(using: .utf8)!)
for item in result {
switch item.type {
case .a:
let casted = item.wrapped as! MyConreteTypeA
print("MyConreteTypeA: (casted)")
case .b:
let casted = item.wrapped as! MyConreteTypeB
print("MyConreteTypeB: (casted)")
}
}
另外,你可以為具體型別實作Decodable,并在根據型別ID屬性確定預期型別后,將解碼委托給它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/332325.html
標籤:
