如何使具有关联值的 Swift 枚举符合 Codable?
How to make a Swift Enum with Associated values conform to Codable?
我会在具有可编码协议的结构中使用枚举。但我不知道,我想为枚举做一个 init
。如果我没有 init
.
,编译器会引发错误
这里的目标是 UpdateIn
类型中的 value
参数可以是两个东西,字符串或 FormFiled
结构。
你知道如何进行初始化吗?
struct UpdateIn: Content {
var keyPath: [String]
var value: Value
var operation: String
}
enum Value: Decodable {
init(from decoder: Decoder) throws {
<#code#>
}
case str(String)
case formField(FormField)
}
struct FormField: Content {
var name: String
var type: String
var options: [String: FormFieldOption]?
var selectedOption: String?
var visibleIfIndIsVisible: Int?
var ind: Int
var mandatory: Bool // TODO: isMandatory
var dateCreatedAt: Date?
var selectItemOtherArbitraryValueEnable: Bool?
var regex: String?
var hasImage: Bool?
var defaultFormFieldOptionId: String?
}
根据回答我尝试提取值并分配给特定变量,但它被拒绝了,你知道为什么吗?
let formField: FormField = params.value
Cannot convert value of type 'Value' to specified type 'FormField'
你只需要切换你的枚举关联值:
enum Value: Codable {
case str(String)
case formField(FormField)
private enum CodingKeys: String, CodingKey {
case str, formField
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .str(string):
try container.encode(string, forKey: .str)
case let .formField(field):
try container.encode(field, forKey: .formField)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
switch container.allKeys.first {
case .str:
self = try .str(container.decode(String.self, forKey: .str))
case .formField:
self = try .formField(container.decode(FormField.self, forKey: .formField))
default:
throw DecodingError.dataCorrupted(
.init(
codingPath: container.codingPath,
debugDescription: "invalid data"
)
)
}
}
}
我会在具有可编码协议的结构中使用枚举。但我不知道,我想为枚举做一个 init
。如果我没有 init
.
这里的目标是 UpdateIn
类型中的 value
参数可以是两个东西,字符串或 FormFiled
结构。
你知道如何进行初始化吗?
struct UpdateIn: Content {
var keyPath: [String]
var value: Value
var operation: String
}
enum Value: Decodable {
init(from decoder: Decoder) throws {
<#code#>
}
case str(String)
case formField(FormField)
}
struct FormField: Content {
var name: String
var type: String
var options: [String: FormFieldOption]?
var selectedOption: String?
var visibleIfIndIsVisible: Int?
var ind: Int
var mandatory: Bool // TODO: isMandatory
var dateCreatedAt: Date?
var selectItemOtherArbitraryValueEnable: Bool?
var regex: String?
var hasImage: Bool?
var defaultFormFieldOptionId: String?
}
根据回答我尝试提取值并分配给特定变量,但它被拒绝了,你知道为什么吗?
let formField: FormField = params.value
Cannot convert value of type 'Value' to specified type 'FormField'
你只需要切换你的枚举关联值:
enum Value: Codable {
case str(String)
case formField(FormField)
private enum CodingKeys: String, CodingKey {
case str, formField
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .str(string):
try container.encode(string, forKey: .str)
case let .formField(field):
try container.encode(field, forKey: .formField)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
switch container.allKeys.first {
case .str:
self = try .str(container.decode(String.self, forKey: .str))
case .formField:
self = try .formField(container.decode(FormField.self, forKey: .formField))
default:
throw DecodingError.dataCorrupted(
.init(
codingPath: container.codingPath,
debugDescription: "invalid data"
)
)
}
}
}