swift - Swift:如何从 Type 对象列出结构中的字段?
问题描述
我想提取 a 中的字段列表,struct
只使用Type
对象。
public struct CoordinateData: Codable {
var longitude: Double?
var latitude: Double?
}
我收到Codable.Type
(在这个阶段,我不知道对象是什么CoordinateData
,我想让我的解决方案对任何对象都通用Codable
)我想提取 ["longitude", "latitude"] ( [String]
)
我尝试使用Mirror
它,当我知道对象的确切类型并且类型为空初始值设定项时,它可以工作:
let metatype: CoordinateData.Type = CoordinateData.self
let c3 = metatype.init()
let m3 = Mirror(reflecting: c3)
for (property, value) in m3.children {
guard let property = property else {
print("no proeprty")
continue
}
print(property)
}
Codable.Type
但是当我所拥有的只是因为它只有一种方法需要我没有.init()
的解码器时,这个解决方案不起作用。.init(from: Decoder)
有什么建议吗?
解决方案
这可以工作,但你需要考虑一些事情。
func mirror<T: Any>(object: T) {
let c3 = object
let m3 = Mirror(reflecting: c3)
for (property, _) in m3.children {
guard let property = property else {
print("no proeprty")
continue
}
print(property)
}
}
利用:mirror(object: CoordinateData())
mirror(object: Foo())
你总是需要传递一个初始化的对象。
这将从函数中删除 init 责任,因为据我所知,您无法初始化通用对象,因为它们是通用的。
所以绕过对象本身这对你有用。
更新:由于没有明确的结构类型参数,这也可能被滥用,但传递任何不是对象的参数都不会给出任何结果,这可以通过将结构更改为类并传递<T>
as来解决<T: AnyObject>
。
您也可以这样做,因为Mirror
参数已经是Any
类型,所以我们可以扩展Mirror
它自己以在getProperties()
下面进行功能检查。
extension Mirror {
func getProperties() -> [String] {
self.children.compactMap { child in
guard let property = child.label else {
return nil
}
return property
}
}
}
用法:var list = Mirror(reflecting: Foo()).getProperties()
这将始终为您提供一个字符串数组,但是如果没有属性,它将返回一个空数组。