如果值是“ RawRepresentable”,如何从“任何”中提取“ rawValue”

时间:2019-04-02 13:57:17

标签: swift generics reflection

我正在寻找类似的东西

func extractRawValue(fromPossibleRawRepresentable value: Any) -> Any? {
    return (value as? RawRepresentable)?.rawValue
}

我不在乎提取的RawValue是否需要为静态类型...

func extractRawValue<T: RawRepresentable, U>(fromPossibleRawRepresentable value: Any, expecting: U.Type) -> U? where T.RawValue == U {
    return (value as? T)?.rawValue
}

上下文:我想在镜像中收集原始值而不是实际值。

let d = Mirror(reflecting: self).children.reduce(into: [String: String](), {
    guard let label = $1.label else {
        return
    }
    $0[label] = extractRawValue(fromPossibleRawRepresentable: $1.value)
}

1 个答案:

答案 0 :(得分:0)

问题在于RawRepresentable有一个associatedtype,因此您无法为其分配Any。您也不能将其用作泛型类型,因为这样一来,您就必须在函数签名中使用具体类型本身,这会违背目的。

您可以使用以下方法轻松解决这些问题:

protocol RawString {
    var rawValue: String { get }
}

这将允许您使用以下方法提取值:

func extractRawValue(value: Any) -> String? {
    return (value as? RawString)?.rawValue
}

对于要从中提取rawValue作为String的任何类型,只需添加与RawString的一致性,例如

enum Foo: String, RawString {}

// or

struct StringContainer: RawString {
   var rawValue: String
}

此方法的缺点是您需要显式标记每种类型以符合RawString,但很遗憾,我看不到其他任何方式。