对枚举中的静态/计算属性进行内省和迭代

时间:2019-02-19 00:06:31

标签: swift enums introspection swift-protocols

CaseIterable协议可让您遍历枚举的情况,除了静态属性外,我想这样做,并获取其值。您将如何实现理论上的PropertyIterable协议?

我尝试使用反射(Mirror(reflecting:)),它适用于结构而不适用于枚举

例如:

protocol PropertyIterable {
  var allProperties: [String: T] { get }  //will get you [String: Any/T]
}

FYI :也许计算属性allProprties定义不正确。但这只是出于说明目的

enum Test: PropertyIterable {
  static let foo = "blah"
  static let bar = "blah2"
}


let test = Test.allProperties //will return ["foo": "blah", bar: "blah2"]

当前,当我打印Mirror(describing: Test.self).children时,我得到了:

AnyCollection<(label: Optional<String>, value: Any)>(_box: Swift._RandomAccessCollectionBox<Swift.LazyMapCollection<Swift.Range<Swift.Int>, (label: Swift.Optional<Swift.String>, value: Any)>>)

1 个答案:

答案 0 :(得分:0)

如果我们使用 CaseIterable,我们应该能够使用 allCases.reduce 将它从 [Test] 减少到 [Test:String]

记住使您的枚举符合 String 以便访问 rawValue

protocol PropertyIterable: Hashable, CaseIterable {
    var rawValue: String { get }
    static var allProperties: [Self: String] { get }
}
extension PropertyIterable {
    static var allProperties: [Self: String] {
        allCases.reduce([Self:String]()) {
            var newValue = $0
            newValue[$1] = $1.rawValue
            return newValue
        }
    }
}

enum Test: String, PropertyIterable {
    case foo = "blah"
    case bar = "blah2"
}

let test = Test.allProperties
print(test) // prints: [Test.bar: "blah2", Test.foo: "blah"]