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

Swift中如何传入泛型结构体并获取其属性列表

解决Swift泛型函数获取结构体属性名返回空数组的问题

你的泛型函数返回空数组的核心原因是:你传入并反射的是结构体的元类型(TestModel.Type),而非结构体的实例。Mirror对元类型进行反射时,只会识别类型的静态成员,不会返回实例的存储属性,因此得到空数组。

下面提供两种可行的解决方案:

方案1:传入结构体实例(推荐)

修改泛型函数,直接反射传入的实例对象,而非元类型:

func propertyNames<T>(structure: T) -> [String] {
    // 反射传入的实例,而非T.self
    let mirror = Mirror(reflecting: structure)
    // 提取所有非空的属性标签
    return mirror.children.compactMap { $0.label }
}

调用方式(传入实例):

let model = TestModel(id: 1, secondsSinceEpoch: 2)
let propertyList = propertyNames(structure: model)
// 输出结果:["id", "secondsSinceEpoch"]

方案2:直接传入元类型(无需创建实例)

如果希望直接通过元类型(如TestModel.self)获取属性名,需要先创建一个结构体实例再反射。这里可以通过自定义协议约束结构体实现默认初始化器:

步骤1:定义默认初始化协议

protocol DefaultInitializable {
    init()
}

步骤2:让你的结构体遵循协议

extension TestModel: DefaultInitializable {
    init() {
        self.id = 0
        self.secondsSinceEpoch = 0
    }
}

步骤3:实现元类型版的泛型函数

func propertyNames<T: DefaultInitializable>(type: T.Type) -> [String] {
    let instance = T()
    let mirror = Mirror(reflecting: instance)
    return mirror.children.compactMap { $0.label }
}

调用方式(传入元类型):

let propertyList = propertyNames(type: TestModel.self)
// 输出结果:["id", "secondsSinceEpoch"]

注意事项

  • Mirror只会反射存储属性,计算属性不会被包含在结果中。
  • 如果你的结构体已经遵循Codable,也可以通过解码空数据创建临时实例,但这种方式在结构体包含非可选属性时会解码失败,不如自定义初始化器可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:13:11