Nếu tôi có một enum với các trường hợp a, b, c, d thì tôi có thể ép kiểu chuỗi "a" là enum được không?
Câu trả lời:
Chắc chắn rồi. Enums có thể có một giá trị thô. Để trích dẫn các tài liệu:
Giá trị thô có thể là chuỗi, ký tự hoặc bất kỳ kiểu số nguyên hoặc dấu phẩy động nào
- Trích từ: Apple Inc. “Ngôn ngữ lập trình Swift.” iBooks. https://itun.es/us/jEUH0.l ,
Vì vậy, bạn có thể sử dụng mã như sau:
enum StringEnum: String
{
case one = "one"
case two = "two"
case three = "three"
}
let anEnum = StringEnum(rawValue: "one")!
print("anEnum = \"\(anEnum.rawValue)\"")
Lưu ý: Bạn không cần phải viết = "một", v.v. sau mỗi trường hợp. Các giá trị chuỗi mặc định giống với tên trường hợp, vì vậy việc gọi .rawValue
sẽ chỉ trả về một chuỗi
Nếu bạn cần giá trị chuỗi để chứa những thứ như khoảng trắng không hợp lệ như một phần của giá trị chữ hoa thì bạn cần đặt chuỗi một cách rõ ràng. Vì thế,
enum StringEnum: String
{
case one
case two
case three
}
let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")
cho
anEnum = "một"
Nhưng nếu bạn muốn case
one
hiển thị "giá trị một", bạn sẽ cần cung cấp các giá trị chuỗi:
enum StringEnum: String
{
case one = "value one"
case two = "value two"
case three = "value three"
}
Hashable
loại nào .
case one = "uno"
. Bây giờ, làm thế nào để phân tích cú pháp "one"
thành giá trị enum? (không thể sử dụng tài liệu thô, vì chúng được sử dụng để bản địa hóa)
= "one"
vv sau mỗi trường hợp. Các giá trị chuỗi mặc định giống như tên trường hợp.
Tất cả bạn cần là:
enum Foo: String {
case a, b, c, d
}
let a = Foo(rawValue: "a")
assert(a == Foo.a)
let 💩 = Foo(rawValue: "💩")
assert(💩 == nil)
Trong Swift 4.2, giao thức CaseIterable có thể được sử dụng cho một enum với rawValues, nhưng chuỗi phải khớp với các nhãn trường hợp enum:
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 }
}
}
sử dụng:
print(MyCode.withLabel("one")) // Optional(MyCode.one)
print(MyCode(rawValue: "uno")) // Optional(MyCode.one)
Trong trường hợp với một enum có kiểu Int, bạn có thể làm như vậy:
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
}
}
Và sử dụng:
let string = "Two"
if let item = MenuItem.enumFromString(string) {
//in this case item = 1
//your code
}
enumFromString
phương pháp cho mỗi enum bạn sử dụng có vẻ điên rồ.
Mở rộng câu trả lời của 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)
}
}
Swift 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
}
}
Đối với Int enum và biểu diễn chuỗi của chúng, tôi khai báo enum như sau:
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
}
}
}
Sử dụng:
order.orderState = OrderState.waiting.rawValue
let orderState = OrderState.init(rawValue: order.orderState)
let orderStateStr = orderState?.description ?? ""
print("orderStateStr = \(orderStateStr)")