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
ma11hew28
quelle
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.

DevAndArtist
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.

GoZoner
quelle
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"
ma11hew28
quelle
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
32

In Swift 3 können Sie dies verwenden

var enumValue = Customer.Physics
var str = String(describing: enumValue)

von Swift, wie man enum verwendet, um den String-Wert zu erhalten

Danil Shaykhutdinov
quelle
2
Dies ist wirklich hilfreich, besonders wenn mein enumnicht auf Strings
daspianist
1
"\(enumValue)"Macht das Gleiche. ^^
Eonist
Dies ist eine bessere Antwort. Es ist nicht erforderlich, dass Sie Ihren Enum-String-Typ angeben.
Scord
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"
Simple99
quelle
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!"
Par
quelle
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"
gbdavid
quelle
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
Tsukimi
quelle
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)
        }
     }
 }
Vivek Gani
quelle
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.

Adriano Spadoni
quelle
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())
Dhruv Ramani
quelle
0

Ab Swift 3.0 können Sie

var str = String(describing: Audience.friends)
iosMentalist
quelle