if-let Any to RawRepresentable <string>

时间:2017-04-27 19:10:37

标签: swift generics swift-protocols

我们假设:

enum MyEnum: String { case value }
let possibleEnum: Any = MyEnum.value
if let str = stringFromPossibleEnum(possibleEnum: possibleEnum)

在不知道枚举类型名称的情况下实施stringFromPossibleEnum的最佳选择是什么?

func stringFromPossibleEnum(possibleEnum: Any) -> String? {
//    how should this be implemented without knowing enum type name?
}

UPD:好的,它会越来越好,我可以判断possibleEnum是否为枚举:

if Mirror(reflecting: possibleEnum).displayStyle == .enum { print("yes!") }

但是如何判断这是基于String的枚举?

UPD: this tweet表示您可以从Enum获得rawValue任意内容。然后,您可以检查rawValue是否为String。但是如何从rawValue获取Mirror

2 个答案:

答案 0 :(得分:3)

好的,所以现在基本上不能开箱即用,因为你不能as? - 强制转换为RawRepresentable,而Mirror不提供rawValue对于枚举。

我想说最好的办法是自己制作protocol,为基于String的{​​{1}}提供默认实施,并按照以下方式手动符合所有枚举:

假设这些是枚举:

RawRepresentable

enum E1: String { case one } enum E2: String { case two } enum E3: String { case three } 协议和默认实现:

StringRawRepresentable

将所有需要的现有枚举符合协议:

protocol StringRawRepresentable {
    var stringRawValue: String { get }
}

extension StringRawRepresentable 
where Self: RawRepresentable, Self.RawValue == String {
    var stringRawValue: String { return rawValue }
}

现在我们可以转发extension E1: StringRawRepresentable {} extension E2: StringRawRepresentable {} extension E3: StringRawRepresentable {}

StringRawRepresentable

答案 1 :(得分:0)

不确定你真正想要在这里实现什么,但现在是:

enum MyEnum: String {
    case A
    case B
    case C
}

func stringFromEnum<T: RawRepresentable>(_ value: T) -> String
    where T.RawValue == String {
    return value.rawValue
}

print(stringFromEnum(MyEnum.A))
print(stringFromEnum(MyEnum.B))
print(stringFromEnum(MyEnum.C))