Swift: Enum değeri dize dönüştürmek?


141

Aşağıdaki numaralandırma göz önüne alındığında:

enum Audience {
    case Public
    case Friends
    case Private
}

Nasıl dize alırım "Public"dan audienceaşağıda sabiti?

let audience = Audience.Public

2
lütfen bu cevabı kontrol edin, size böyle bir şeyi nasıl başarabileceğinizle ilgili bazı fikirler verebilir: stackoverflow.com/questions/24648726/enums-with-data-in-swift/…
holex

Swift 2 ve xcode7'de kodunuzda herhangi bir değişiklik yapmanız gerekmez, sadece şunu kullanınprint("\(audience)")
gbdavid

7
Swift ekolünün şimdi böyle çok güncel cevaplarla dolu olmasından nefret ediyorum. XCode8.2 / Swift3 olarak, bu kadar kolayString(describing: yourEnumValue)
Travis Griggs

@TravisGriggs Xcode 11.4 için artık
çalışmaz

Yanıtlar:


156

Bu özelliğin hangi Swift sürümüne eklendiğinden emin değilim, ancak şu anda ( Swift 2.1 ) sadece bu koda ihtiyacınız var:

enum Audience : String {
    case public
    case friends
    case private
}

let audience = Audience.public.rawValue // "public"

Ham değerler için dizeler kullanıldığında, her vaka için örtük değer , o vakanın adının metnidir .

[...]

enum CompassPoint : String {
    case north, south, east, west
}

Yukarıdaki örnekte, CompassPoint.south öğesinin örtük ham değeri "south", vb. Vardır.

Bir numaralandırma vakasının ham değerine rawValue özelliği ile erişirsiniz:

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

Kaynak.


8
xcode7.3 swift2.2, i gibi şeyler yaparsanız: enum değerinin gerçek dize temsili değil türü olan print("appState: \(application.applicationState)") olsun appState: UIApplicationState. Burada bir şey mi eksik? (PS: rawValue için sadece Int değerini alıyorum ...)
Martin

@Cyrus, senaryonuz bu konuda sorulandan farklı. .rawValuenumaralandırmanın ham değerini döndürür. Seninki public enum UIApplicationState : Intgerçekten de tip Int. Ayrıca Apple belgelerinden alıntı yapan cevabımı hiç okumadınız. ... Hala UIApplicationStatedizeye dönüştürmek istiyorsanız, UIApplicationStateözel bir hesaplanmış özellik ile genişletmenizi öneririmextension UIApplicationState { var toString() -> String { /* check self for all diff. cases and return something like "Active" */ }
DevAndArtist

Dize türü olmayan numaralandırmalara sahip olan sorunu çözmez
denis631

1
@ denis631 ne demek? Ham bir enum tipi herhangi bir şey olabilir. Bir enum, OptionSetgerçekten istiyorsanız bile uyum sağlayabilir . Ve asıl soru zaten Dizeler hakkında.
DevAndArtist

1
benim numaram böyle yazılırsa, enum Test: Int {case A, B}, rawValue elbette int geri dönecektir, aradığımız davanın adını bir String olarak almanın bir yoludur. @DanilShaykhutdinov tam da bunu yaptı. Cevabına bakın ve asıl soruda enumun Dize veya Int değil türü yoktur.
denis631

210

'String almak' için deyimsel arayüz arayüzü kullanmak CustomStringConvertible ve descriptionalıcıya erişmek . Olarak tanımlayın enum:

enum Foo : CustomStringConvertible {
  case Bing
  case Bang
  case Boom
  
  var description : String { 
    switch self {
    // Use Internationalization, as appropriate.
    case .Bing: return "Bing"
    case .Bang: return "Bang"
    case .Boom: return "Boom"
    }
  }
}

Eylemde:

 > let foo = Foo.Bing
foo: Foo = Bing
 > println ("String for 'foo' is \(foo)"
String for 'foo' is Bing

Güncel : Swift> = 2.0 için, yerini PrintableileCustomStringConvertible

Not : Kullanmak CustomStringConvertible, Foofarklı bir ham türün benimsenmesine izin verir . Örneğin enum Foo : Int, CustomStringConvertible { ... }mümkündür. Bu özgürlük faydalı olabilir.


2
Println dizesini oluşturmanın bir başka kısa yolu: "'foo' için dize (foo)"
John MP Knox

3
@ JohnM.P.Knox, "foo için dize \ (foo)" dizesinde olduğu gibi ters eğik çizgiyi unutmayın. Edit OK, editör ondan kurtuluyor, görünmesi için 2 tanesini girmek zorunda kaldım
zmit

Ne anlamı var CustomStringConvertiblebu onsuz sadece ince olarak çalışıyor olur?
Daniel van der Merwe

3
CustomStringConvertibledescriptionher numaralandırma durumu için hangi dizginin kullanılacağına karar vermenize izin veren tanımlamanızı / belirlemenizi gerektirir - bu kesinlikle uluslararasılaşma ve kod okunabilirliği açısından önemlidir. Bunları umursamıyorsanız, 'enum Foo: String {/ * ... * /} `
GoZoner

2
Numaralandırmanız bir String değilse veya rawValue'dan farklı bir dize istiyorsanız, bu doğru yanıttır. @ denis631
Haagenti

32

Şimdilik, sıralamayı şu şekilde yeniden tanımlayacağım:

enum Audience: String {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"
}

böylece yapabilirim:

audience.toRaw() // "Public"

Ancak, bu yeni numaralandırma tanımı gereksiz değil mi? İlk numaralandırma tanımını tutabilir ve şöyle bir şey yapabilir miyim:

audience.toString() // "Public"

3
Xcode 7 Beta 3'ten itibaren cevabınızı yazabilirsiniz, ancak vermezseniz = Stringotomatik olarak ham bir değer (davanın adı) alır.
Qbyte

3
.ToString () yerine şimdi .rawValue kullanın
SoftDesigner

Swift 1.2'de şunları kullanabilirsiniz: println (Audience.Friends.rawValue)
Oleg Popov


24

Ben kullanmak ister Printablebirlikte Raw Values.

enum Audience: String, Printable {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"

    var description: String {
        return self.rawValue
    }
}

Sonra yapabiliriz:

let audience = Audience.Public.description // audience = "Public"

veya

println("The value of Public is \(Audience.Public)") 
// Prints "The value of Public is Public"

1
Bu cevabı seçilen cevaptan daha iyi seviyorum çünkü yapabileceğimAudience(rawValue: "Friends")
tidwall

12

Xcode 7 GM sürümü için güncellendi. Şimdi umduğum gibi çalışıyor - teşekkürler Apple!

enum Rank:Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}

let r = Rank.Ace

print(r)               // prints "Ace"
print("Rank: \(r)!")   // prints "Rank: Ace!"

2
Swift 2.0'da, uygunluk CustomStringConvertibleaslında print(r)bu durumda kullanılmasına izin verecektir .
matm

Xcode 7 beta 4'te yansıtma (), Mirror lehine devre dışı bırakılmış gibi görünüyor (yansıtan: x). Ancak, döndürülen nesnenin farklı bir yapısı vardır.
GSnyder

1
Cevabı güncelleyin lütfen
Ben Sinclair

10

Swift 2 ve en son Xcode 7'de bundan daha basit olamazdı (numaralandırma türünü veya .rawValue, tanımlayıcıları vb. Belirtmeye gerek yok ...)

Swift 3 ve Xcode 8 için güncellendi:

    enum Audience {
        case Public
        case Friends
        case Private
    }

    let audience: Audience = .Public  // or, let audience = Audience.Public
    print(audience) // "Public"

Int destekli enums ile mükemmel çalıştı
chrislarson

Sadece bir gözlem: Bu, kendi oluşturduğunuz numaralandırmalar için çalışır ancak HKWorkoutActivityType gibi bir şey için çalışmaz
Ace Green

Yerelleştirilmiş dizelerin yanı sıra;)
Eugene Braginets

2
Asıl soru, enum değerini kendi numaralarınızdaki dizeye dönüştürmekti, bu yüzden cevap verdim ... UIKit / AppKit Enums ile uğraşmak istiyorsanız, elbette farklı bir hikaye.
gbdavid

1
@gbdavid - UIKit / AppKit Enums için Q var mı? Google'ı aradım ve bulamadım. Gerekirse Q gönderebilirim.
benc

8

Numaralandırma'da Ints kullanılıyorsa hızlı bir 3 ve üzeri örnek

public enum ECategory : Int{
        case Attraction=0, FP, Food, Restroom, Popcorn, Shop, Service, None;
        var description: String {
            return String(describing: self)
        }
    }

let category = ECategory.Attraction
let categoryName = category.description //string Attraction

Zarif bir çözüm. "\ (kategori)" veya doğrudan Dize (açıklayan: kategori) de çalışır. Int numaralandırmalar için bile.
t1ser

8

"Swift Programlama Dili" nin "Hızlı Tur" bölümündeki örneği okuyan ve simpleDescription () yöntemini basitleştirmenin bir yolunu arayan herkes, bunu yaparak numaralandırmanın kendisini String'e dönüştürür String(self):

enum Rank: Int
{
    case Ace = 1 //required otherwise Ace will be 0
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
            case .Ace, .Jack, .Queen, .King:
                return String(self).lowercaseString
            default:
                return String(self.rawValue)
        }
     }
 }

2
Sadece "@objc" ile numaralandırma kullanmadığınızdan emin olun. Bu, bu yaklaşımın başarısız olmasına neden olur.
Matt Bearson

5

Birkaç farklı yol denedikten sonra kullanmak istemiyorsanız buldum:

let audience = Audience.Public.toRaw()

Hala bir yapı kullanarak arşivleyebilirsiniz

struct Audience {
   static let Public  = "Public"
   static let Friends = "Friends"
   static let Private = "Private"
}

kodunuz:

let audience = Audience.Public

beklendiği gibi çalışacaktır. Bu hoş değil ve bazı dezavantajları var, çünkü bir "enum" kullanmıyorsunuz, sadece kısayol kullanamazsınız.


Düzgün görünüyor. Bu özel durum için en iyi uygulamanın ne olacağını merak ediyorum. Basitlik nedeniyle struct sözdizimini kullanmayı tercih ederim ama enum yerine struct kullanmak doğru görünmüyor, ya da sadece ben mi? Peki, hiçbir şey sadece sabit değişkenleri başka bir yerde beyan etmenizi engellemez, bu sefer onu bir yapı içine eklersiniz böylece organize olur. Düşünceler?
schystz

Tam olarak, sabit değişkenler olarak çalışır, ancak daha organize olur. Daha önce söylediğim gibi, tek sorun "anahtar durum" ve ".Private" kısayolları. Uygulamanızı sıfırdan oluşturuyorsanız, "enum" ile gitmeye çalışın, yalnızca "enum" herhangi bir nedenle kodunuzu karşılamıyorsa yapıları kullanın. Ben şahsen sabit değişkenleri önlemek her zaman yerine yapıları kullanmak.
Adriano Spadoni

Bunu varsayılan anahtarlar için kullanıyorum. Bir uygulamadaki varsayılan tuşları hatırlamak yerine, tuşları bir yapıya döküp oradan çekiyorum.
Adrian

3

Bunu yapmanın birçok yolu vardır. Ya numaralandırmada enum türünün değerine göre dizeyi döndüren bir işlev tanımlayabilirsiniz:

enum Audience{
    ...
func toString()->String{
  var a:String

  switch self{
   case .Public:
    a="Public"
   case .Friends:
    a="Friends"
   ...
 }
 return a
}

Veya bunu deneyebilirsiniz:

enum Audience:String{
   case Public="Public"
   case Friends="Friends"
   case Private="Private"
}

Ve kullanmak için:

var a:Audience=Audience.Public
println(a.toRaw())

1

Swift 3.0'dan başlayarak şunları yapabilirsiniz:

var str = String(describing: Audience.friends)

1
İnanılmaz, ama bu mükemmel çalışıyor. "Deyimsel" yaklaşımdan çok daha kısa. Teşekkürler!
Roman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.