if-let Any 到 RawRepresentable<String>

问题描述 投票:0回答:3

让我们假设一下:

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: 此推文建议您可以从枚举中获取

rawValue
作为 Any。然后您可能可以检查
rawValue
是否为
String
。但是如何从
rawValue
得到
Mirror
呢?

swift generics swift-protocols
3个回答
5
投票

好吧,所以目前这基本上是不可行的,因为你不能

as?
转换为
RawRepresentable
,并且
Mirror
不为枚举提供
rawValue

我想说最好的选择是自己制作

protocol
,为基于
String
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
:

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

stringFromPossibleEnum(possibleEnum: E2.two as Any)

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

0
投票

基于 Danni P 的回答

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


func stringFromPossibleEnum(possibleEnum: Any) -> String? {
    if let e = possibleEnum as? (any RawRepresentable),
       let str = e.rawValue as? String {
        return str
    }
    return nil
}

stringFromPossibleEnum(possibleEnum: E2.two as Any)
© www.soinside.com 2019 - 2024. All rights reserved.