if-let Any to RawRepresentable<String>

穿精又带淫゛_ 提交于 2019-12-30 11:19:28

问题


Let's assume this:

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

What's my best bet of implementing stringFromPossibleEnum without knowing enum type name?

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

UPD: ok, it's getting better, with this I can tell if possibleEnum is an enum:

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

But how to tell if that's a String-based enum?

UPD: this tweet suggests that you can get rawValue as Any from Enum. You can probably then check if that rawValue is String. But how to get rawValue from Mirror?


回答1:


Ok, so this is basically not doable currently out of the box, as you can't as?-cast to RawRepresentable, and Mirror does not provide rawValue for enums.

I'd say the best bet is to make own protocol, provide default implementation for String-based RawRepresentable and conform all enums manually like so:

Assuming these are the enums:

enum E1: String { case one }
enum E2: String { case two }
enum E3: String { case three }

StringRawRepresentable protocol and default implementation:

protocol StringRawRepresentable {
    var stringRawValue: String { get }
}

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

Conform all needed existing enums to the protocol:

extension E1: StringRawRepresentable {}
extension E2: StringRawRepresentable {}
extension E3: StringRawRepresentable {}

And now we can cast to StringRawRepresentable:

func stringFromPossibleEnum(possibleEnum: Any) -> String? {
    if let e = possibleEnum as? StringRawRepresentable { return e.stringRawValue }
    return nil
}

stringFromPossibleEnum(possibleEnum: E2.two as Any)



回答2:


Not sure what you're really trying to achieve here, but here it is:

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))


来源:https://stackoverflow.com/questions/43666118/if-let-any-to-rawrepresentablestring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!