【问题标题】:How to get enum from raw value in Swift?如何从 Swift 中的原始值中获取枚举?
【发布时间】:2016-07-11 03:14:22
【问题描述】:

我正在尝试从原始值获取枚举类型:

enum TestEnum: String {
    case Name
    case Gender
    case Birth

    var rawValue: String {
        switch self {
        case .Name: return "Name"
        case .Gender: return "Gender"
        case .Birth: return "Birth Day"
        }
    }
}

let name = TestEnum(rawValue: "Name")       //Name
let gender = TestEnum(rawValue: "Gender")   //Gender

但似乎rawValue 不适用于带空格的字符串:

let birth = TestEnum(rawValue: "Birth Day") //nil

有什么获取方法的建议吗?

【问题讨论】:

标签: ios swift enums


【解决方案1】:

太复杂了,直接给case赋值就行了

enum TestEnum: String {
  case Name = "Name"
  case Gender = "Gender"
  case Birth = "Birth Day"
}

let name = TestEnum(rawValue: "Name")!       //Name
let gender = TestEnum(rawValue: "Gender")!   //Gender
let birth = TestEnum(rawValue: "Birth Day")! //Birth

如果案例名称与原始值匹配,您甚至可以省略它

enum TestEnum: String {
  case Name, Gender, Birth = "Birth Day"
}

在 Swift 3+ 中,所有枚举情况都是 lowercased

【讨论】:

  • 除了变量name等现在是可选的,这不太可能是OP想要的。
  • 除了接收可选的返回之外别无他法(除非你想崩溃,当传递一个字符串时,它不对应于枚举大小写)。
  • @matt - 对,但是由于您在编译时知道案例名称,因此您可以安全地打开选项。我编辑了答案。
  • 强制解开从其 RawValue 创建的枚举可能会导致运行时异常。最好使用“if let”构造来展开值。另见:Apple Enum Raw Value documentation
  • @Hugo 如果原始值是用户定义的变量,你是对的。另一方面,枚举案例的数量不能在运行时更改,并且开发人员(您)知道这些值。因此,如果初始化枚举的原始值是 文字字符串,则运行时错误会显示设计错误。
【解决方案2】:

完整的工作示例:

enum TestEnum: String {
    case name = "A Name"
    case otherName
    case test = "Test"
}

let first: TestEnum? = TestEnum(rawValue: "A Name")
let second: TestEnum? = TestEnum(rawValue: "OtherName")
let third: TestEnum? = TestEnum(rawValue: "Test")

print("\(first), \(second), \(third)")

所有这些都可以,但是当使用原始值初始化时,它将是可选的。如果这是一个问题,您可以为枚举创建一个初始化程序或构造函数来尝试处理这个问题,添加一个 none 案例并在无法创建枚举时返回它。像这样的:

static func create(rawValue:String) -> TestEnum {
        if let testVal = TestEnum(rawValue: rawValue) {
            return testVal
        }
        else{
            return .none
        }
    }

【讨论】:

  • init(_ str: String) { self = TestEnum(rawValue: str) ?? .none } 作为额外的 init 执行相同的操作
  • 这是另一种选择。如果可能的话,我个人更喜欢避免使用相同类型参数的初始化。
【解决方案3】:

使用 Swift 4.2CaseIterable 协议一点也不难!

这是一个如何实现它的示例。

import UIKit

private enum DataType: String, CaseIterable {
    case someDataOne = "an_awesome_string_one"
    case someDataTwo = "an_awesome_string_two"
    case someDataThree = "an_awesome_string_three"
    case someDataFour = "an_awesome_string_four"

    func localizedString() -> String {
        // Internal operation
        // I have a String extension which returns its localized version
        return self.rawValue.localized
    }

    static func fromLocalizedString(localizedString: String) -> DataType? {
        for type in DataType.allCases {
            if type.localizedString() == localizedString {
                return type
            }
        }
        return nil
    }

}

// USAGE EXAMPLE
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let dataType = DataType.fromLocalizedString(localizedString: self.title) {
        loadUserData(type: dataType)
    }
}

您可以轻松修改它以根据 rawValue 返回 DataType。希望对你有帮助!

【讨论】:

  • 如果需要从本地化字符串恢复枚举大小写,我认为设计有问题。
  • @Leo,完全可以讨论从本地化字符串中检索枚举大小写是否理想。事实上,我个人同意你的看法,事实并非如此——但有时我们在大型项目中工作,我们不能简单地继续前进并改变我们想要的任何东西。也就是说,当我说这种讨论超出范围时,我想你会同意我的看法……关键是你可以从任何给定的关联类型中检索枚举案例。它回答了您从 2016 年开始的第一个问题。干杯!
【解决方案4】:

你可以这样define enum -

enum TestEnum: String {
    case Name, Gender, Birth
}

enum TestEnum: String {
    case Name
    case Gender
    case Birth
}

您可以提供一个 init 方法,该方法默认为成员值之一。

enum TestEnum: String {
    case Name, Gender, Birth

    init() {
        self = .Gender
    }
}

在上面的例子中,TestEnum.Name 有一个隐含的原始值“Name”,等等。

您可以使用其 rawValue 属性访问枚举案例的原始值:

let testEnum = TestEnum.Name.rawValue
// testEnum is "Name"
let testEnum1 = TestEnum() 
// testEnum1 is "Gender"

【讨论】:

    【解决方案5】:

    使用枚举显示原始值

    import UIKit
    
    enum car: String {
        case bmw =  "BMW"
        case jaquar = "JAQUAR"
        case rd = "RD"
        case benz = "BENZ"
    
    }
    
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var label: UILabel!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            label.text = car.bmw.rawValue
    
        }
    
    
    }
    

    【讨论】:

      【解决方案6】:

      这里是 swift 4.1 中更有用的代码示例

      import UIKit
      
      enum FormData {
        case userName
        case password
      
        static let array = [userName, password]
      
        var placeHolder: String {
          switch self {
          case .userName:
            return AppString.name.localized // will return "Name" string
          case .password:
            return AppString.password.localized // will return "Password" string
          }
        }
      }
      
      enum AppString: String {
        case name = "Name"
        case password = "Password"
      
        var localized: String {
          return NSLocalizedString(self.rawValue, comment: "")
        }
      }
      

      【讨论】:

        【解决方案7】:

        我认为这是 swift 4.2 的一个快速而干净的解决方案(你可以 c&p 到操场)

        import UIKit
        
        public enum SomeEnum: String, CaseIterable {
            case sun,moon,venus,pluto
        }
        
        let str = "venus"
        let newEnum = SomeEnum.allCases.filter{$0.rawValue == str}.first
        // newEnum is optional
        if let result = newEnum {
            print(result.rawValue)
        }
        

        【讨论】:

          【解决方案8】:
          enum withdrawBalceTimeGenrateError : String ,  Error{
              case insufficientBalance = "Plz Check Balance"
          }
          
          
          withdrawBalceTimeGenrateError.insufficientBalance.rawValue // Plz Check Balance
          

          【讨论】:

          • 最有帮助的答案通常是代码以及如何/为什么使用代码的解释。您在这里没有错,但多一点努力将有助于使这成为一个高质量的答案。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多