你可以从它的大小写的名称初始化一个枚举值(*不*它的RawValue?)

时间:2017-12-14 01:15:56

标签: swift enums initialization

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

enum MyTestEnum : Int{
    case one     = 1
    case eight   = 8
    case unknown = -1
}

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

let value = MyTestEnum(rawValue:-1)

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

let value = MyTestEnum(caseName:"eight")

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

enum MyOtherEnum{
    case xxx
    case yyy
    case zzz
}

let value = MyOtherEnum(caseName:"xxx")

那可以这样做吗?

思想:

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

4 个答案:

答案 0 :(得分:2)

基于CodeBender的solution,这是此情况的不错扩展

extension CaseIterable {

    ///Note: case value and name can be different
    init?(caseName: String) {
        for v in Self.allCases where "\(v)" == caseName {
            self = v
            return
        }
        return nil
    }
}

答案 1 :(得分:1)

您可以使用自定义初始化程序

extension MyTestEnum {
    public static func allValues() -> [MyTestEnum] {
        let retVal = AnySequence { () -> AnyIterator<MyTestEnum> in
            var raw = 0
            return AnyIterator {
                let current = withUnsafePointer(to: &raw) {
                    $0.withMemoryRebound(to: MyTestEnum.self, capacity: 1) { $0.pointee }
                }
                guard current.hashValue == raw else { return nil }
                raw += 1
                return current
            }
        }

        return [MyTestEnum](retVal)
    }

    init?(caseName: String){
        for v in MyTestEnum.allValues() {
            if "\(v)" == caseName {
                self = v
                return
            }
        }
        self = MyTestEnum.unknown
    }
}

let test = MyTestEnum(caseName: "eight")

或简单地手动完成所有情况:)

extension MyTestEnum {
 init?(caseName: String){
   switch caseName {
     case "eight": self.init(rawValue: 8)
     case "one": self.init(rawValue: 1)
     default: self.init(rawValue: -1)
   }
 }
}

let test1 = MyTestEnum(caseName: "eight") 
let test2 = MyTestEnum(rawValue: 1)

希望这会有所帮助!!

答案 2 :(得分:0)

听起来您希望枚举案例具有原始DataFrame原始Int值。这样做并不是非常可能,但也许这很接近:

String

现在您可以从案例名称初始化,但您也可以在需要时检索enum MyTestEnum : String { case one case eight case unknown var intValue: Int { switch self { case one: return 1 case eight: return 8 case unknown: return -1 } } } 。 (如果需要,您可以轻松添加一个可用的初始化程序,以允许从整数初始化。)

答案 3 :(得分:0)

在Swift 4.2中,现在使用print(count(1)) print(count(1, z=10)) 很容易做到这一点。

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 } } 是否与初始化时传递的"\value"相匹配。

找到匹配项后,将设置caseName,循环结束。否则,将返回self进行通话。

下面是两个有效的例子和两个失败的例子:

nil