你能从它的 case 名称初始化一个 Enum 值吗(*不是*它的 RawValue?)

Mar*_*eIV 0 enums initialization swift

考虑这个枚举(注意它的类型是Int

enum MyTestEnum : Int{
    case one     = 1
    case eight   = 8
    case unknown = -1
}
Run Code Online (Sandbox Code Playgroud)

您可以根据原始值轻松初始化此版本,如下所示...

let value = MyTestEnum(rawValue:-1)
Run Code Online (Sandbox Code Playgroud)

我试图找出它是否可以用案例名称本身的字符串表示来初始化(同样,不是原始值,而是“案例”之后的词),就像这样......

let value = MyTestEnum(caseName:"eight")
Run Code Online (Sandbox Code Playgroud)

注意:如果可能,我希望它可以与任何枚举一起使用,无论其原始值类型如何。比如这个...

enum MyOtherEnum{
    case xxx
    case yyy
    case zzz
}

let value = MyOtherEnum(caseName:"xxx")
Run Code Online (Sandbox Code Playgroud)

那么这能做到吗?

想法:

  • 我认为 Swift 有一种方法可以在给定表示完全限定类名的字符串的情况下实例化一个类。也许可以在这里使用类似的东西。

Cod*_*der 7

在 Swift 4.2 中,现在使用CaseIterable.

enum MyOtherEnum: CaseIterable {
    case xxx
    case yyy
    case zzz
    
    init?(caseName: String) {
        for value in MyOtherEnum.allCases where "\(value)" == caseName {
            self = value
            return
        }
        
        return nil
    }
}

enum MyTestEnum: Int, CaseIterable{
    case one     = 1
    case eight   = 8
    case unknown = -1
    
    init?(caseName: String) {
        for value in MyTestEnum.allCases where "\(value)" == caseName {
            self = value
            return
        }
        
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里做的是创建一个可失败的初始化程序,它遍历所有潜在的情况,测试以查看"\(value)"(返回该潜在情况的名称)是否与caseName传递给初始化程序的参数匹配。

当找到匹配项时,self设置 并且循环结束。否则,nil为调用返回。

下面是两个工作示例和两个失败示例:

let myOtherEnum = MyOtherEnum(caseName:"xxx")
print(myOtherEnum) // MyOtherEnum.xxx

let myTestEnum = MyTestEnum(caseName:"eight")
print(myTestEnum?.rawValue) // 8

let myOtherEnumFail = MyOtherEnum(caseName:"aaa")
print(myOtherEnumFail) // nil

let myTestEnumFail = MyTestEnum(caseName:"ten")
print(myTestEnumFail) // nil
Run Code Online (Sandbox Code Playgroud)