在 Swift 中如何从原始值获取枚举?

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

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

有什么建议吗?

90213 次浏览

Too complicated, just assign the raw values directly to the cases

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

If the case name matches the raw value you can even omit it

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

In Swift 3+ all enum cases are lowercased

You can define enum like this -

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

OR

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

you can provide an init method which defaults to one of the member values.

enum TestEnum: String {
case Name, Gender, Birth


init() {
self = .Gender
}
}

In the example above, TestEnum.Name has an implicit raw value of "Name", and so on.

You access the raw value of an enumeration case with its rawValue property:

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

Full working example:

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)")

All of those will work, but when initializing using a raw value it will be an optional. If this is a problem you could create an initializer or constructor for the enum to try and handle this, adding a none case and returning it if the enum couldn't be created. Something like this:

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

Here is example of more useable code in 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: "")
}
}

With Swift 4.2 and CaseIterable protocol it is not that hard at all!

Here is an example of how to implement it.

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)
}
}

You can easily modify it to return the DataType based on the rawValue. I hope it helps!

Display the rawvalue using Enum

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


}




}

I think this is a quick and clean solution for swift 4.2 (you can c&p to playground)

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)
}
enum withdrawBalceTimeGenrateError : String ,  Error{
case insufficientBalance = "Plz Check Balance"
}




withdrawBalceTimeGenrateError.insufficientBalance.rawValue // Plz Check Balance