You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@propertyWrapper实现Decodable时如何兼容可选缺失键?

问题原因

  • Swift 自动合成Decodable实现时,会将加了属性包装器的属性的属性包装器类型本身作为解码目标,而非它的wrappedValue类型
  • 你的SomeKindOfBool类型本身是非可选的,因此自动合成逻辑会强制校验对应键必须存在,找不到就抛出Swift.DecodingError.keyNotFound错误,和wrappedValue是否为可选没有关联

解决方案

有两种常用的实现方案,都可以满足键缺失时自动解码为nil的需求:

方案1:扩展KeyedDecodingContainer统一处理同类场景

这个方案不需要修改原有业务层的属性声明,只需要添加全局扩展适配所有带可选值的属性包装器解码场景:

// 先声明属性包装器约束协议
protocol PropertyWrapper {
    associatedtype WrappedValue
    init(wrappedValue: WrappedValue)
}

extension KeyedDecodingContainer {
    // 重载解码方法,针对wrappedValue为可选的属性包装器做特殊处理
    func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T : Decodable, T: PropertyWrapper, T.WrappedValue: ExpressibleByNilLiteral {
        if let value = try decodeIfPresent(type, forKey: key) {
            return value
        } else {
            // 键不存在时直接返回wrappedValue为nil的包装器实例
            return T(wrappedValue: nil)
        }
    }
}

// 给你的自定义属性包装器遵守该协议
extension SomeKindOfBool: PropertyWrapper {
    init(wrappedValue: Bool?) {
        self.wrappedValue = wrappedValue
    }
}

方案2:直接给属性添加默认值

直接给加了属性包装器的属性添加默认值= nil,编译器会自动识别为键不存在时使用该默认值,无需强制校验键存在:
首先给属性包装器补充支持默认值的构造器:

@propertyWrapper
struct SomeKindOfBool: Decodable {
    var wrappedValue: Bool?
    
    // 新增支持默认值的构造器
    init(wrappedValue: Bool?) {
        self.wrappedValue = wrappedValue
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let stringifiedValue = try? container.decode(String.self) {
            switch stringifiedValue.lowercased() {
            case "false": wrappedValue = false
            case "true": wrappedValue = true
            default: wrappedValue = nil
            }
        } else {
            wrappedValue = try? container.decode(Bool.self)
        }
    }
}

然后修改MyType的属性声明,添加默认值:

public struct MyType: Decodable {
    @SomeKindOfBool var someKey: Bool? = nil
}

两种方案修改完成后,你的原有测试代码都可以正常运行,输出结果为:

true
false
nil

内容的提问来源于stack exchange,提问作者Ortwin Gentz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:15:08