if-let Any для RawRepresentable<String>
Давайте предположим это:
enum MyEnum: String { case value }
let possibleEnum: Any = MyEnum.value
if let str = stringFromPossibleEnum(possibleEnum: possibleEnum)
Какой мой лучший вариант реализации stringFromPossibleEnum
не зная имя типа enum?
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
на основе enum?
UPD: этот твит предполагает, что вы можете получить rawValue
как любой из Enum. Вы можете тогда проверить, если это rawValue
является String
, Но как получить rawValue
от Mirror
?
3 ответа
Хорошо, так что это в принципе не выполнимо в настоящее время из коробки, так как вы не можете 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))
На основе ответа Дэнни П.
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)