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

Swift跨模块为Model扩展Decodable时遇错误求助

解决跨模块为结构体扩展Decodable时的初始化错误

出现这两个错误的核心原因:

  • 结构体LabelModel在模块1中是public访问级别,但它的默认成员初始化器是internal的,跨模块(模块2)无法直接调用
  • 在自定义init(from:)初始化器中,必须确保结构体的所有存储属性完成初始化,或者调用一个可访问的初始化器来完成self的初始化

方法一:为模块1的LabelModel添加public默认初始化器

修改模块1的LabelModel代码,显式添加一个public的默认初始化器:

public struct LabelModel {
    public var value: String?
    
    // 添加public默认初始化器,让跨模块可以调用
    public init() {}
}

修改模块2的Decodable扩展,先调用默认初始化器初始化self,再赋值属性:

extension LabelModel: Decodable {
    enum CodingKeys: String, CodingKey {
        case value
    }

    public init(from decoder: Decoder) throws {
        // 先调用public默认初始化器完成self初始化
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        value = try container.decodeIfPresent(String.self, forKey: .value)
    }
}

方法二:为模块1的LabelModel添加public成员初始化器

修改模块1的LabelModel,显式声明public的成员初始化器:

public struct LabelModel {
    public var value: String?
    
    // 显式声明public成员初始化器
    public init(value: String?) {
        self.value = value
    }
}

在模块2的扩展中,直接调用这个成员初始化器完成self的初始化:

extension LabelModel: Decodable {
    enum CodingKeys: String, CodingKey {
        case value
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let decodedValue = try container.decodeIfPresent(String.self, forKey: .value)
        // 调用public成员初始化器完成self初始化
        self.init(value: decodedValue)
    }
}

内容的提问来源于stack exchange,提问作者Asif Raza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:24:59