让我们假设一下:
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
呢?
好吧,所以目前这基本上是不可行的,因为你不能
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)
不确定你真正想在这里实现什么,但它是:
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))
基于 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)