if-let Any 到 RawRepresentable<String>
if-let Any to RawRepresentable<String>
让我们假设:
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
作为 Any。然后您可能可以检查 rawValue
是否为 String
。但是如何从 Mirror
得到 rawValue
呢?
不确定您在这里真正想要实现的目标是:
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))
好的,所以这基本上是目前开箱即用的,因为你不能 as?
-cast 到 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 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
作为 Any。然后您可能可以检查 rawValue
是否为 String
。但是如何从 Mirror
得到 rawValue
呢?
不确定您在这里真正想要实现的目标是:
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))
好的,所以这基本上是目前开箱即用的,因为你不能 as?
-cast 到 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)