Swift: Enum-Wert in String konvertieren?


141

Angesichts der folgenden Aufzählung:

enum Audience {
    case Public
    case Friends
    case Private
}

Wie erhalte ich die Zeichenfolge "Public"aus der folgenden audienceKonstante?

let audience = Audience.Public

2
Bitte überprüfen Sie diese Antwort, es kann Ihnen einige Ideen geben, wie Sie so etwas erreichen können: stackoverflow.com/questions/24648726/enums-with-data-in-swift/…
holex

in Swift 2 und xcode7 müssen Sie nichts an Ihrem Code ändern, verwenden Sie einfachprint("\(audience)")
gbdavid

7
Ich hasse es, dass die Swift-Ökoscape jetzt mit sehr veralteten Antworten wie diesen gefüllt ist. Ab XCode8.2 / Swift3 ist es so einfach wieString(describing: yourEnumValue)
Travis Griggs

@TravisGriggs Es funktioniert nicht mehr für Xcode 11.4
DawnSong

Antworten:


156

Sie sind sich nicht sicher, in welcher Swift-Version diese Funktion hinzugefügt wurde, aber im Moment ( Swift 2.1 ) benötigen Sie nur diesen Code:

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

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

Wenn Zeichenfolgen für Rohwerte verwendet werden, ist der implizite Wert für jeden Fall der Text des Falls dieses Falls .

[...]

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

Im obigen Beispiel hat CompassPoint.south den impliziten Rohwert "Süd" usw.

Sie greifen auf den Rohwert eines Aufzählungsfalls mit seiner Eigenschaft rawValue zu:

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

Quelle.


8
in xcode7.3 swift2.2, wenn ich Dinge mache wie: print("appState: \(application.applicationState)") Ich bekomme, appState: UIApplicationState welches der Typ und nicht die tatsächliche Zeichenfolgendarstellung des Enum-Werts ist. Vermisse ich hier etwas? (PS: für rawValue bekomme ich nur den Int-Wert ...)
Martin

@ Cyrus Ihr Szenario unterscheidet sich von dem, das in diesem Thread gefragt wurde. .rawValuegibt den Rohwert Ihrer Aufzählung zurück. Ihre ist in public enum UIApplicationState : Intder Tat von Typ Int. Sie haben auch nie meine Antwort gelesen, die ein Zitat aus Apple-Dokumenten enthält. ... Wenn Sie immer noch in einen UIApplicationStateString konvertieren möchten, würde ich Ihnen empfehlen, ihn UIApplicationStatemit einer benutzerdefinierten berechneten Eigenschaft zu erweiternextension UIApplicationState { var toString() -> String { /* check self for all diff. cases and return something like "Active" */ }
DevAndArtist

Löst das Problem nicht mit Aufzählungen, die nicht vom Typ String sind
denis631

1
@ denis631 was meinst du? Der rohe Typ einer Aufzählung kann alles sein. Eine Aufzählung kann sich sogar anpassen, OptionSetwenn Sie wirklich wollen. Und die ursprüngliche Frage betrifft sowieso Strings.
DevAndArtist

1
Wenn meine Aufzählung so geschrieben ist, enum Test: Int {case A, B}, gibt der rawValue natürlich int zurück. Wir suchen nach einer Möglichkeit, den Namen des Falls als String abzurufen. Genau das hat @DanilShaykhutdinov getan. Schauen Sie sich seine Antwort an und in der ursprünglichen Frage hat die Aufzählung keinen Typ, keinen String oder Int.
denis631

208

Die idiomatische Schnittstelle zum Abrufen eines Strings besteht darin, die CustomStringConvertible Schnittstelle zu verwenden und auf den descriptionGetter zuzugreifen . Definieren Sie Ihre enumals:

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"
    }
  }
}

In Aktion:

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

Aktualisiert : Für Swift> = 2.0, ersetzt PrintabledurchCustomStringConvertible

Hinweis : Mit "Verwenden" CustomStringConvertiblekönnen Sie Fooeinen anderen Rohtyp übernehmen. Zum Beispiel enum Foo : Int, CustomStringConvertible { ... }ist möglich. Diese Freiheit kann nützlich sein.


2
Eine andere kürzere Möglichkeit, die Druckzeichenfolge zu erstellen, ist: "Zeichenfolge für 'foo' ist (foo)"
John MP Knox

3
@ JohnM.P.Knox vergiss den Schrägstrich nicht wie in "String für 'foo' ist \ (foo)". Bearbeiten OK, es ist der Editor, der es loswird, ich musste 2 davon eingeben, damit es
angezeigt wird

Was bringt es, CustomStringConvertiblewenn dies ohne es genauso gut funktioniert?
Daniel van der Merwe

3
CustomStringConvertibleErmöglicht / erfordert, dass Sie definieren, mit descriptionwelcher Option Sie entscheiden können, welche Zeichenfolge für jeden Enum-Fall verwendet werden soll - dies ist sicher wichtig für die Internationalisierung und möglicherweise für die Lesbarkeit des Codes. Wenn Sie sich nicht für diese interessieren, können Sie 'enum Foo: String {/ * ... * /} `
GoZoner

2
Dies ist die richtige Antwort, wenn Ihre Aufzählung kein String ist oder Sie einen anderen String als den rawValue möchten. @ denis631
Haagenti

32

Im Moment werde ich die Aufzählung neu definieren als:

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

damit ich tun kann:

audience.toRaw() // "Public"

Aber ist diese neue Aufzählungsdefinition nicht überflüssig? Kann ich die ursprüngliche Aufzählungsdefinition beibehalten und etwas tun wie:

audience.toString() // "Public"

3
Ab Xcode 7 Beta 3 können Sie Ihre Antwort einfach schreiben, jedoch ohne, = Stringda sie automatisch einen Rohwert (Name des Falls) erhält, wenn Sie keinen angeben.
Qbyte

3
Anstelle von .toString () verwenden Sie jetzt .rawValue
SoftDesigner

In Swift 1.2 können Sie verwenden: println (Audience.Friends.rawValue)
Oleg Popov


24

Ich benutze gerne Printablemit Raw Values.

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

    var description: String {
        return self.rawValue
    }
}

Dann können wir tun:

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

oder

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

1
Ich mag diesen Weg besser als die ausgewählte Antwort, weil ich es tun kannAudience(rawValue: "Friends")
tidwall

12

Aktualisiert für die Veröffentlichung von Xcode 7 GM. Es funktioniert so, wie man es sich jetzt erhoffen würde - danke 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
In Swift 2.0 CustomStringConvertiblewürde die Konformität mit nur print(r)in diesem Fall die Verwendung ermöglichen .
Matm

In Xcode 7 Beta 4 scheint Reflect () zugunsten von Mirror deaktiviert worden zu sein (Reflect: x). Das zurückgegebene Objekt hat jedoch eine andere Struktur.
GSnyder

1
Aktualisieren Sie die Antwort bitte
Ben Sinclair

10

Einfacher geht es in Swift 2 und dem neuesten Xcode 7 nicht (es ist nicht erforderlich, den Aufzählungstyp oder .rawValue, Deskriptoren usw. anzugeben.)

Aktualisiert für Swift 3 und Xcode 8:

    enum Audience {
        case Public
        case Friends
        case Private
    }

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

Funktionierte perfekt mit meinen von Int unterstützten Enums
chrislarson

Nur eine Beobachtung: Dies funktioniert für selbst erstellte Enums, aber nicht für so etwas wie HKWorkoutActivityType
Ace Green

Sowie für lokalisierte Saiten;)
Eugene Braginets

2
Die ursprüngliche Frage betraf die Konvertierung des Enum-Werts in einen String in Ihren eigenen Enums. Deshalb habe ich eine Antwort darauf gegeben ... Wenn Sie mit UIKit / AppKit-Enums umgehen möchten, ist das natürlich eine andere Geschichte.
Gbdavid

1
@gbdavid - Gibt es ein Q für UIKit / AppKit-Enums? Ich habe gegoogelt und konnte es nicht finden. Ich kann Q einreichen, wenn dies erforderlich ist.
Benc

8

Ein schnelles Beispiel ab 3, wenn Ints in Enum verwendet wird

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

Eine elegante Lösung. "\ (Kategorie)" oder direkt String (Beschreibung: Kategorie) würde ebenfalls funktionieren. Auch für Int enums.
2.

8

Für alle , die beispielsweise in „A Swift Tour“ Kapitel von „Der Swift Programmiersprache“ und sucht nach einem Weg , um den simpleDescription () -Methode zu vereinfachen, Umwandeln des ENUM selbst zu String lesen , indem Sie String(self)wird es tun:

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
Stellen Sie nur sicher, dass Sie die Aufzählung nicht mit "@objc" verwenden. Dies führt dazu, dass dieser Ansatz fehlschlägt.
Matt Bearson

5

Nachdem ich einige verschiedene Möglichkeiten ausprobiert hatte, stellte ich fest, dass, wenn Sie nicht verwenden möchten:

let audience = Audience.Public.toRaw()

Sie können es weiterhin mit einer Struktur archivieren

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

dann dein Code:

let audience = Audience.Public

wird wie erwartet funktionieren. Es ist nicht schön und es gibt einige Nachteile, weil Sie keine "Aufzählung" verwenden. Sie können die Verknüpfung nicht verwenden, indem Sie nur .Private hinzufügen, und es funktioniert auch nicht mit Switch-Fällen.


Sieht ordentlich aus. Ich frage mich, was für diesen speziellen Fall die beste Vorgehensweise wäre. Ich würde die Struktur-Syntax wegen der Einfachheit bevorzugen, aber die Verwendung von Struktur anstelle von Enum scheint nicht richtig zu sein, oder vielleicht bin es nur ich? Nun, nichts hindert Sie daran, konstante Variablen irgendwo anders zu deklarieren. Dieses Mal fügen Sie sie einfach in eine Struktur ein, damit sie organisiert ist. Gedanken?
Schystz

Genau, es funktioniert als konstante Variablen, aber besser organisiert. Wie ich bereits sagte, ist das einzige Problem das "Switch Case" und die Verknüpfungen ".Private". Wenn Sie Ihre App von Grund auf neu erstellen, versuchen Sie, mit "enum" zu arbeiten. Verwenden Sie Strukturen nur, wenn die "enum" Ihren Code aus irgendeinem Grund nicht erfüllt. Ich persönlich vermeide Konstantenvariablen und verwende stattdessen immer Strukturen.
Adriano Spadoni

Ich benutze dies für Standardschlüssel. Anstatt mich an Standardschlüssel in einer App zu erinnern, speichere ich die Schlüssel in einer Struktur und ziehe sie von dort ab.
Adrian

3

Es gibt mehrere Möglichkeiten, dies zu tun. Sie können entweder eine Funktion in der Aufzählung definieren, die die Zeichenfolge basierend auf dem Wert des Aufzählungstyps zurückgibt:

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

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

Oder Sie können dies versuchen:

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

Und um es zu benutzen:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.