我试图使具有不同关联值的枚举符合 Decodable 协议(protocol),但在关联值部分遇到问题。
enum SportType: Decodable {
case team(String, String) //Two team names
case individual([String]) //List of player names
}
我已经成功获得了一个符合 Decodable 的枚举,但没有关联值,但在使用关联值做同样的事情时遇到了困难。
//Works but no associated values
enum SportType: String, Decodable {
case team, case individual
}
最佳答案
您需要创建一个自定义 init(from detector: Decoder) throws
,并将关联值视为对象中的普通字段,使用 CodingKeys
进行解码他们。详细信息取决于关联值在编码对象中的实际表示方式。
例如,如果您的值编码为:
{ "team1": "aaa", "team2": "bbb" }
和
{ "individual": ["x", "y", "z"]}
你可以:
enum SportType: Decodable {
case team(String, String) //Two team names
case individual([String]) //List of player names
// Define associated values as keys
enum CodingKeys: String, CodingKey {
case team1
case team2
case individual
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Try to decode as team
if let team1 = try container.decodeIfPresent(String.self, forKey: .team1),
let team2 = try container.decodeIfPresent(String.self, forKey: .team2) {
self = .team(team1, team2)
return
}
// Try to decode as individual
if let individual = try container.decodeIfPresent([String].self, forKey: .individual) {
self = .individual(individual)
return
}
// No luck
throw DecodingError.dataCorruptedError(forKey: .individual, in: container, debugDescription: "No match")
}
}
测试:
let encoded = """
{ "team1": "aaa", "team2": "bbb" }
""".data(using: .utf8)
let decoded = try? JSONDecoder().decode(SportType.self, from: encoded!)
switch decoded {
case .team(let a, let b):
print("I am a valid team with team1=\(a), team2=\(b)")
case .individual(let a):
print("I am a valid individual with individual=\(a)")
default:
print("I was not parsed :(")
}
打印:
I am a valid team with team1=aaa, team2=bbb
关于ios - 使具有关联值的枚举符合可解码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66092907/