Pada Xcode 7 beta 5 (Swift versi 2) Anda sekarang dapat mencetak nama-nama jenis dan kasus enum secara default menggunakan print(_:)
, atau mengkonversi ke String
menggunakan String
's init(_:)
sintaks initializer atau interpolasi string. Jadi untuk contoh Anda:
enum City: Int {
case Melbourne = 1, Chelyabinsk, Bursa
}
let city = City.Melbourne
print(city)
// prints "Melbourne"
let cityName = "\(city)" // or `let cityName = String(city)`
// cityName contains "Melbourne"
Jadi tidak ada lagi kebutuhan untuk mendefinisikan & memelihara fungsi kenyamanan yang mengaktifkan setiap case untuk mengembalikan string literal. Selain itu, ini berfungsi secara otomatis untuk enum apa pun, bahkan jika tidak ada tipe nilai mentah yang ditentukan.
debugPrint(_:)
& String(reflecting:)
dapat digunakan untuk nama yang sepenuhnya memenuhi syarat:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Perhatikan bahwa Anda dapat menyesuaikan apa yang dicetak dalam masing-masing skenario ini:
extension City: CustomStringConvertible {
var description: String {
return "City \(rawValue)"
}
}
print(city)
// prints "City 1"
extension City: CustomDebugStringConvertible {
var debugDescription: String {
return "City (rawValue: \(rawValue))"
}
}
debugPrint(city)
// prints "City (rawValue: 1)"
(Saya belum menemukan cara untuk memanggil nilai "default" ini, misalnya, untuk mencetak "Kota adalah Melbourne" tanpa menggunakan kembali ke pernyataan peralihan. Menggunakan \(self)
dalam implementasi description
/ debugDescription
menyebabkan rekursi tak terbatas.)
Komentar di atas String
's init(_:)
& init(reflecting:)
initializers menjelaskan dengan tepat apa yang dicetak, tergantung pada jenis sesuai tercermin ke:
extension String {
/// Initialize `self` with the textual representation of `instance`.
///
/// * If `T` conforms to `Streamable`, the result is obtained by
/// calling `instance.writeTo(s)` on an empty string s.
/// * Otherwise, if `T` conforms to `CustomStringConvertible`, the
/// result is `instance`'s `description`
/// * Otherwise, if `T` conforms to `CustomDebugStringConvertible`,
/// the result is `instance`'s `debugDescription`
/// * Otherwise, an unspecified result is supplied automatically by
/// the Swift standard library.
///
/// - SeeAlso: `String.init<T>(reflecting: T)`
public init<T>(_ instance: T)
/// Initialize `self` with a detailed textual representation of
/// `subject`, suitable for debugging.
///
/// * If `T` conforms to `CustomDebugStringConvertible`, the result
/// is `subject`'s `debugDescription`.
///
/// * Otherwise, if `T` conforms to `CustomStringConvertible`, the result
/// is `subject`'s `description`.
///
/// * Otherwise, if `T` conforms to `Streamable`, the result is
/// obtained by calling `subject.writeTo(s)` on an empty string s.
///
/// * Otherwise, an unspecified result is supplied automatically by
/// the Swift standard library.
///
/// - SeeAlso: `String.init<T>(T)`
public init<T>(reflecting subject: T)
}
Lihat catatan rilis untuk info tentang perubahan ini.
print(enum)
Anda dapat menggunakanString(enum)
CLAuthorizationStatus
enum di dalamlocationManager didChangeAuthorizationStatus
callback delegate Anda, Anda perlu mendefinisikan ekstensi protokol. Misalnya:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- setelah Anda melakukan ini, itu akan berfungsi seperti yang Anda harapkan: print ("Auth status: (\ status))".Tidak ada introspeksi pada kasus enum saat ini. Anda harus mendeklarasikannya secara manual:
Jika Anda ingin jenis mentah menjadi Int, Anda harus melakukan pergantian sendiri:
sumber
get { ... }
bagian untuk singkatnya jika Anda tidak mendefinisikan setter.enum City : String, CustomStringConvertible {
. Sebagai bagian dari protokol CSC, Anda kemudian perlu mengubah properti menjadi publik , misalnya:public var description : String {
Di Swift-3 (diuji dengan Xcode 8.1) Anda dapat menambahkan metode berikut di enum Anda:
Anda kemudian dapat menggunakannya sebagai pemanggilan metode normal pada instance enum Anda. Mungkin juga bekerja di versi Swift sebelumnya, tetapi saya belum mengujinya.
Dalam contoh Anda:
Jika Anda ingin memberikan fungsionalitas ini ke semua enum Anda, Anda bisa menjadikannya sebagai ekstensi:
Ini hanya berfungsi untuk enums Swift.
sumber
Untuk Objective-C
enum
, satu-satunya cara saat ini tampaknya, misalnya, untuk memperpanjang enum denganCustomStringConvertible
berakhir dengan sesuatu seperti:Dan kemudian casting
enum
sebagaiString
:sumber
The
String(describing:)
initializer dapat digunakan untuk mengembalikan nama label kasus bahkan untuk enum dengan rawValues non-String:Perhatikan bahwa ini tidak berfungsi jika enum menggunakan
@objc
pengubah:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-descriptioning/27327
Antarmuka Swift yang Dihasilkan untuk tipe Objective-C terkadang tidak termasuk
@objc
pengubah. Namun demikian, Enums tersebut didefinisikan dalam Objective-C, dan karenanya tidak berfungsi seperti di atas.sumber
Di atas dukungan String (...) (CustomStringConvertible) untuk enum di Swift 2.2, ada juga dukungan refleksi yang agak rusak untuk mereka. Untuk kasus enum dengan nilai terkait, dimungkinkan untuk mendapatkan label kasus enum menggunakan refleksi:
Namun, dengan dipatahkan, maksud saya adalah untuk enum "sederhana",
label
properti yang dihitung berdasarkan refleksi di atas baru saja kembalinil
(boo-hoo).Situasi dengan refleksi seharusnya menjadi lebih baik setelah Swift 3, tampaknya. Solusi untuk saat ini adalah
String(…)
, seperti yang disarankan dalam salah satu jawaban lain:sumber
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
Ini sangat mengecewakan.
Untuk kasus ketika Anda membutuhkan nama-nama (bahwa kompiler dengan sempurna mengetahui ejaan yang tepat, tetapi menolak untuk membiarkan akses - terima kasih tim Swift !! -) tetapi tidak ingin atau tidak dapat menjadikan String sebagai basis enum Anda, sebuah verbose, alternatif rumit adalah sebagai berikut:
Anda dapat menggunakan hal di atas sebagai berikut:
Dan Anda akan mendapatkan hasil yang diharapkan (kode untuk Kolom serupa, tetapi tidak ditampilkan)
Di atas, saya telah membuat
description
properti merujuk kembali kestring
metode, tetapi ini adalah masalah selera. Perhatikan juga bahwastatic
variabel yang disebut harus memiliki ruang lingkup yang memenuhi syarat dengan nama tipe penutupnya, karena kompiler terlalu amnesik dan tidak dapat mengingat konteksnya dengan sendirinya ...Tim Swift harus benar-benar diperintahkan. Mereka menciptakan enum yang tidak bisa Anda gunakan
enumerate
dan yang bisa Anda gunakanenumerate
adalah "Urutan" tetapi tidakenum
!sumber
Saya menabrak pertanyaan ini dan ingin berbagi cara sederhana untuk membuat Fungsi sulap yang disebutkan
sumber
Swift sekarang memiliki apa yang dikenal sebagai Nilai Baku yang Ditetapkan Secara Implisit . Pada dasarnya jika Anda tidak memberikan nilai mentah untuk setiap case dan enum bertipe String, itu menyimpulkan bahwa nilai mentah case itu sendiri dalam format string. Ayo coba.
sumber
Untuk Swift:
jika variabel "batteryState" Anda kemudian panggil:
sumber
Sederhana tapi berfungsi ...
sumber