首页 > 解决方案 > 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)

有什么建议吗?

标签: swiftstructintrospectionmirror

解决方案


这可以工作,但你需要考虑一些事情。

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() 这将始终为您提供一个字符串数组,但是如果没有属性,它将返回一个空数组。


推荐阅读