如果我有一个包含 a、b、c、d 情况的枚举,我可以将字符串“a”转换为枚举吗?
当然。枚举可以有原始值。引用文档:
原始值可以是字符串、字符或任何整数或 浮点数类型
— 摘自:Apple Inc.“Swift 编程语言”。 iBooks。 https://itun.es/us/jEUH0.l,
所以你可以使用这样的代码:
enum StringEnum: String
{
case one = "value one"
case two = "value two"
case three = "value three"
}
let anEnum = StringEnum(rawValue: "value one")!
print("anEnum = \"\(anEnum.rawValue)\"")
注意:不需要在每个case后面都写=“one”等。默认字符串值与案例名称相同,因此调用
.rawValue
将仅返回一个字符串
如果您需要字符串值包含空格等作为 case 值的一部分无效的内容,那么您需要显式设置该字符串。所以,
enum StringEnum: String
{
case one
case two
case three
}
let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")
给予
anEnum =“一”
但是如果您希望
case
one
显示“值一”,您将需要提供字符串值:
enum StringEnum: String
{
case one = "value one"
case two = "value two"
case three = "value three"
}
在 Swift 4.2 中,CaseIterable 协议可用于具有 rawValues 的枚举,但字符串应与枚举 case 标签匹配:
enum MyCode : String, CaseIterable {
case one = "uno"
case two = "dos"
case three = "tres"
static func withLabel(_ label: String) -> MyCode? {
return self.allCases.first{ "\($0)" == label }
}
}
用途:
print(MyCode.withLabel("one")) // Optional(MyCode.one)
print(MyCode(rawValue: "uno")) // Optional(MyCode.one)
您所需要的是:
enum Foo: String {
case a, b, c, d
}
let a = Foo(rawValue: "a")
assert(a == Foo.a)
let 💩 = Foo(rawValue: "💩")
assert(💩 == nil)
如果是 Int 类型的枚举,您可以这样做:
enum MenuItem: Int {
case One = 0, Two, Three, Four, Five //... as much as needs
static func enumFromString(string:String) -> MenuItem? {
var i = 0
while let item = MenuItem(rawValue: i) {
if String(item) == string { return item }
i += 1
}
return nil
}
}
并使用:
let string = "Two"
if let item = MenuItem.enumFromString(string) {
//in this case item = 1
//your code
}
借鉴 djruss70 的答案来创建高度通用的解决方案:
extension CaseIterable {
static func from(string: String) -> Self? { Self.allCases.first { string == "\($0)" } }
func toString() -> String { "\(self)" }
}
用途:
enum Chassis: CaseIterable {
case pieridae, oovidae
}
let chassis: Chassis = Chassis.from(string: "oovidae")!
let string: String = chassis.toString()
注意:不幸的是,如果枚举被声明为 @objc,这将不起作用。 据我所知,从 Swift 5.3 开始,除了强力解决方案(switch 语句)之外,没有办法让它与 @objc 枚举一起工作。
如果有人碰巧知道一种方法可以使 @objc 枚举工作,我会对答案非常感兴趣。
斯威夫特 4.2:
public enum PaymentPlatform: String, CaseIterable {
case visa = "Visa card"
case masterCard = "Master card"
case cod = "Cod"
var nameEnum: String {
return Mirror(reflecting: self).children.first?.label ?? String(describing: self)
}
func byName(name: String) -> PaymentPlatform {
return PaymentPlatform.allCases.first(where: {$0.nameEnum.elementsEqual(name)}) ?? .cod
}
}
扩展 Duncan C 的答案
extension StringEnum: StringLiteralConvertible {
init(stringLiteral value: String){
self.init(rawValue: value)!
}
init(extendedGraphemeClusterLiteral value: String) {
self.init(stringLiteral: value)
}
init(unicodeScalarLiteral value: String) {
self.init(stringLiteral: value)
}
}
对于 Int 枚举及其 String 表示形式,我声明枚举如下:
enum OrderState: Int16, CustomStringConvertible {
case waiting = 1
case inKitchen = 2
case ready = 3
var description: String {
switch self {
case .waiting:
return "Waiting"
case .inKitchen:
return "InKitchen"
case .ready:
return "Ready"
}
}
static func initialize(stringValue: String)-> OrderState? {
switch stringValue {
case OrderState.waiting.description:
return OrderState.waiting
case OrderState.inKitchen.description:
return OrderState.inKitchen
case OrderState.ready.description:
return OrderState.ready
default:
return nil
}
}
}
用途:
order.orderState = OrderState.waiting.rawValue
let orderState = OrderState.init(rawValue: order.orderState)
let orderStateStr = orderState?.description ?? ""
print("orderStateStr = \(orderStateStr)")
我发现其他答案使这种方式变得更加复杂。这是一个快速简洁的示例。
enum Gender: String {
case male, female, unspecified
}
简单枚举,请注意,我在枚举本身中添加了“: String”以将类型声明为字符串。
现在你所要做的就是:
let example: Gender = Gender(rawValue: "male")
就是这样,“example”现在是一个 Gender 类型的枚举,值为 .male
在 Swift 4+ 中您几乎不需要做任何其他事情。
我用的是这个:
public enum Currency: CaseIterable, Codable {
case AFN = 971 // Afghani (minor=2)
case DZD = 012 // Algerian Dinar (minor=2)
...
private static var cachedLookup: [String: Currency] = [:]
init?(string: String) {
if Self.cachedLookup.isEmpty {
Self.cachedLookup = Dictionary(uniqueKeysWithValues: Self.allCases.map { ("\($0)", $0) })
}
if let currency = Self.cachedLookup[string] {
self = currency
return
} else {
return nil
}
}
}