如何在嵌套枚举解码失败时设置TestStruct的failDecode标志?
解决枚举解码失败时设置结构体标志的问题
你遇到的编译错误很典型——TestStruct.failDecode是实例属性,而在嵌套枚举TestEnum的init(from:)方法里,你并没有创建TestStruct的实例,自然没法直接修改这个属性。而且默认的Codable解码逻辑中,如果枚举解码失败会直接抛出错误,导致整个TestStruct初始化失败,根本没机会设置failDecode。
下面给你两种实用的解决方案,根据你的需求选择即可:
方案一:用可选类型处理解码失败,在结构体初始化中捕获错误
这种方案把testEnum改为可选类型,当枚举解码失败时将其设为nil,同时把failDecode设为true:
struct TestStruct: Codable { var testEnum: TestEnum? // 改为可选类型,解码失败时为nil let failDecode: Bool // 定义编码键,对应JSON中的字段 enum CodingKeys: String, CodingKey { case testEnum } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) do { // 尝试解码枚举,如果成功则标记解码正常 testEnum = try container.decode(TestEnum.self, forKey: .testEnum) failDecode = false } catch { // 解码失败时设置标志,同时将枚举设为nil testEnum = nil failDecode = true } } } extension TestStruct { enum TestEnum: String, Codable { case val1 = "VAL1" case val2 = "VAL2" // 这里不需要自定义init,默认的String枚举解码会在值不匹配时抛出错误 } }
方案二:给枚举新增未知case,保证枚举总有有效值
如果你不想让testEnum为可选类型,可以给枚举加一个.unknown的case,解码失败时用这个case兜底,同时设置failDecode:
struct TestStruct: Codable { let testEnum: TestEnum let failDecode: Bool enum CodingKeys: String, CodingKey { case testEnum } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let rawValue = try container.decode(String.self, forKey: .testEnum) if let enumValue = TestEnum(rawValue: rawValue) { // 匹配到有效枚举值,标记解码成功 testEnum = enumValue failDecode = false } else { // 匹配失败,用未知case兜底,标记解码失败 testEnum = .unknown failDecode = true } } } extension TestStruct { enum TestEnum: String, Codable { case val1 = "VAL1" case val2 = "VAL2" case unknown // 新增兜底case } }
核心思路总结
本质上,你需要把错误处理逻辑从枚举移到结构体的初始化方法中——因为只有在结构体初始化时,才能同时控制枚举的解码结果和failDecode标志的赋值。枚举的初始化方法无法直接操作外部结构体的实例属性,这也是你原来代码编译失败的根本原因。
内容的提问来源于stack exchange,提问作者Hai Nguyen
相关产品推荐
相关产品推荐

