Swift: преобразовать значение enum в String?

Учитывая следующее перечисление:

enum Audience {
    case Public
    case Friends
    case Private
}

Как получить строку "Public" из константы audience ниже?

let audience = Audience.Public

Ответ 1

Не знаю, в какую версию Swift была добавлена ​​эта функция, но прямо сейчас (Swift 2.1) вам нужен только этот код:

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

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

Когда строки используются для необработанных значений, неявное значение для каждого случая это текст этого имени с именами.

[...]

enum CompassPoint: String {
    case North, South, East, West
}

В приведенном выше примере CompassPoint.South имеет неявное исходное значение "Юг" и т.д.

Вы получаете доступ к необработанному значению случая перечисления с его rawValue Свойство:

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

Источник

Ответ 2

Идиоматическим интерфейсом для получения String является использование интерфейса CustomStringConvertible и доступ к getter description. Определите свой 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";
    }
  }
}

В действии:

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

Обновлено: для Swift >= 2.0 замените Printable на CustomStringConvertible

Ответ 3

В настоящее время я переопределяю перечисление как:

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

чтобы я мог:

audience.toRaw() // "Public"

Но разве это новое определение enum избыточно? Могу ли я сохранить начальное определение перечисления и сделать что-то вроде:

audience.toString() // "Public"

Ответ 4

Мне нравится использовать Printable с Raw Values.

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

    var description: String {
        return self.rawValue
    }
}

Тогда мы можем сделать:

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

или

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

Ответ 5

Обновлен для выпуска Xcode 7 GM. Он работает так, как можно было бы надеяться сейчас - спасибо 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!"

Ответ 7

В Swift 2 и последнем Xcode 7 не может быть проще, чем в этом случае (нет необходимости указывать тип перечисления или .rawValue, дескрипторы и т.д.)

Обновлен для Swift 3 и Xcode 8:

    enum Audience {
        case Public
        case Friends
        case Private
    }

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

Ответ 8

Существует несколько способов сделать это. Либо вы можете определить функцию в перечислении, которая возвращает строку на основе значения типа перечисления:

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

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

Или вы могли бы попробовать это:

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

И использовать его:

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

Ответ 9

Для тех, кто читает пример в главе "A Swift Tour" в разделе "Быстрый язык программирования" и ищет способ упростить метод simpleDescription(), преобразование самого перечисления в String с помощью 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)
        }
     }
   }

Ответ 10

Попробуйте несколько разных способов, я обнаружил, что если вы не хотите использовать:

let audience = Audience.Public.toRaw()

Вы все равно можете архивировать его, используя struct

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

то ваш код:

let audience = Audience.Public

будет работать как ожидалось. Это некрасиво, и есть некоторые недостатки, потому что вы не используете "перечисление", вы не можете использовать ярлык, только добавляя .Private не будет работать с случаями коммутатора.

Ответ 11

Быстрый пример 3 и выше, если использовать Ints в Enum

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