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
相关产品推荐
相关产品推荐

