enumStringEnum: String{
case one = "one"case two = "two"case three = "three"
}
let anEnum = StringEnum(rawValue: "one")!
print("anEnum = \"\(anEnum.rawValue)\"")
Catatan: Anda tidak perlu menulis = "one" dll setelah setiap kasus. Nilai string default sama dengan nama kasus sehingga pemanggilan .rawValuehanya akan mengembalikan string
EDIT
Jika Anda memerlukan nilai string untuk memuat hal-hal seperti spasi yang tidak valid sebagai bagian dari nilai kasus, Anda perlu menyetel string secara eksplisit. Begitu,
enumStringEnum: String{
case one
case two
case three
}
let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")
memberi
anEnum = "satu"
Tetapi jika Anda ingin caseonemenampilkan "nilai satu", Anda perlu memberikan nilai string:
enumStringEnum: String{
case one = "value one"case two = "value two"case three = "value three"
}
Nilai mentah harus dapat dikonversi secara literal. Anda tidak dapat menggunakan sembarang Hashablejenis.
Vatsal Manot
1
Oke ... Saya mengutip dokumen Apple, yang mencantumkan jenis nilai yang dapat digunakan sebagai nilai mentah enum. String, pertanyaan OP, adalah salah satu jenis yang didukung.
Duncan C
1
Hmm, bayangkan case one = "uno". Sekarang, bagaimana cara mengurai "one"ke nilai enum? (tidak dapat menggunakan bahan mentah, karena digunakan untuk pelokalan)
Agent_L
Mungkin Anda dapat menginisialisasi String mentah saat inisialisasi bergantung pada pelokalannya ... atau cukup memiliki enum yang berbeda untuk pelokalan yang berbeda. Dalam kasus apapun, seluruh tujuan memiliki enum adalah untuk mengabstraksi raw yang mendasari yaitu lokalisasi. Desain kode yang baik tidak akan meneruskan "uno" sebagai parameter di mana pun, tetapi mengandalkan StringEnum.one
SkyWalker
5
Anda tidak perlu menulis = "one"dll setelah setiap kasus. Nilai string default sama dengan nama kasus.
Ini bukanlah jawaban yang benar secara teknis karena ini memeriksa nilai mentahnya. Dalam contoh di sini seperti yang diberikan, tidak ada nilai mentah yang ditentukan, sehingga secara implisit dicocokkan dengan nama kasus, tetapi jika Anda memiliki enum dengan nilai mentah, ini akan rusak.
Mark A. Donohoe
30
Di Swift 4.2, protokol CaseIterable dapat digunakan untuk enum dengan rawValues, tetapi stringnya harus cocok dengan label enum case:
enumMyCode : String, CaseIterable{
case one = "uno"case two = "dos"case three = "tres"staticfuncwithLabel(_ label: String) -> MyCode? {
returnself.allCases.first{ "\($0)" == label }
}
}
Sungguh gila Anda tidak bisa hanya menggunakan fungsionalitas serupa yang ada di dalam bahasa. Saya dapat membayangkan Anda menyimpan nilai di JSON misalnya dengan nama enum, dan kemudian mengurai perlu mengubahnya kembali. Menulis enumFromStringmetode untuk setiap enum yang Anda gunakan sepertinya gila.
Peterdk
1
@Peterdk, mohon sarankan alternatif terbaik. Solusi Igor sebenarnya hanya berhasil untuk saya.
Hemang
@Hemang Ini berfungsi dengan baik, baiklah, tetapi solusi yang lebih baik adalah dukungan Swift untuk melakukan ini secara otomatis. Sangat gila untuk melakukan ini secara manual untuk setiap enum. Tapi ya, ini berhasil.
Peterdk
@Peterdk, dapatkah Anda menambahkan jawaban terpisah untuk hal yang sama? Itu pasti akan membantu semua orang di sini.
Hemang
1
Tidaklah gila bahwa Swift tidak mendukungnya secara asli. Hal yang gila adalah fungsionalitasnya bergantung pada nama suatu tipe. Ketika nilainya berubah, Anda harus memfaktor ulang dan mengganti nama semua penggunaan. Ini bukanlah cara yang benar untuk menyelesaikan masalah ini.
enumChassis: CaseIterable{
case pieridae, oovidae
}
let chassis: Chassis = Chassis.from(string: "oovidae")!
let string: String = chassis.toString()
Catatan: sayangnya ini tidak akan berfungsi jika enum dideklarasikan @objc. Sejauh yang saya tahu tentang Swift 5.3, tidak ada cara untuk membuat ini bekerja dengan @objc enum kecuali solusi brute force (pernyataan switch).
Jika seseorang mengetahui cara untuk membuat ini bekerja untuk @objc enum, saya akan sangat tertarik dengan jawabannya.
Jawaban:
Tentu. Enum bisa memiliki nilai mentah. Mengutip dokumen:
Jadi Anda bisa menggunakan kode seperti ini:
enum StringEnum: String { case one = "one" case two = "two" case three = "three" } let anEnum = StringEnum(rawValue: "one")! print("anEnum = \"\(anEnum.rawValue)\"")
Catatan: Anda tidak perlu menulis = "one" dll setelah setiap kasus. Nilai string default sama dengan nama kasus sehingga pemanggilan
.rawValue
hanya akan mengembalikan stringEDIT
Jika Anda memerlukan nilai string untuk memuat hal-hal seperti spasi yang tidak valid sebagai bagian dari nilai kasus, Anda perlu menyetel string secara eksplisit. Begitu,
enum StringEnum: String { case one case two case three } let anEnum = StringEnum.one print("anEnum = \"\(anEnum)\"")
memberi
Tetapi jika Anda ingin
case
one
menampilkan "nilai satu", Anda perlu memberikan nilai string:enum StringEnum: String { case one = "value one" case two = "value two" case three = "value three" }
sumber
Hashable
jenis.case one = "uno"
. Sekarang, bagaimana cara mengurai"one"
ke nilai enum? (tidak dapat menggunakan bahan mentah, karena digunakan untuk pelokalan)= "one"
dll setelah setiap kasus. Nilai string default sama dengan nama kasus.Yang kamu butuhkan adalah:
enum Foo: String { case a, b, c, d } let a = Foo(rawValue: "a") assert(a == Foo.a) let 💩 = Foo(rawValue: "💩") assert(💩 == nil)
sumber
Di Swift 4.2, protokol CaseIterable dapat digunakan untuk enum dengan rawValues, tetapi stringnya harus cocok dengan label enum 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 } } }
pemakaian:
print(MyCode.withLabel("one")) // Optional(MyCode.one) print(MyCode(rawValue: "uno")) // Optional(MyCode.one)
sumber
Dalam kasus dengan enum dengan tipe Int Anda dapat melakukannya:
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 } }
Dan gunakan:
let string = "Two" if let item = MenuItem.enumFromString(string) { //in this case item = 1 //your code }
sumber
enumFromString
metode untuk setiap enum yang Anda gunakan sepertinya gila.Memperluas jawaban 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) } }
sumber
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 } }
sumber
Untuk Int enum dan representasi Stringnya, saya mendeklarasikan enum sebagai berikut:
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 } } }
Pemakaian:
order.orderState = OrderState.waiting.rawValue let orderState = OrderState.init(rawValue: order.orderState) let orderStateStr = orderState?.description ?? "" print("orderStateStr = \(orderStateStr)")
sumber
Mengolah jawaban djruss70 untuk membuat solusi yang sangat umum:
extension CaseIterable { static func from(string: String) -> Self? { return Self.allCases.first { string == "\($0)" } } func toString() -> String { "\(self)" } }
Pemakaian:
enum Chassis: CaseIterable { case pieridae, oovidae } let chassis: Chassis = Chassis.from(string: "oovidae")! let string: String = chassis.toString()
Catatan: sayangnya ini tidak akan berfungsi jika enum dideklarasikan @objc. Sejauh yang saya tahu tentang Swift 5.3, tidak ada cara untuk membuat ini bekerja dengan @objc enum kecuali solusi brute force (pernyataan switch).
Jika seseorang mengetahui cara untuk membuat ini bekerja untuk @objc enum, saya akan sangat tertarik dengan jawabannya.
sumber