如何获得Swift中的枚举值的名称?

如果我有一个枚举Integer原始值:

 enum City: Int { case Melbourne = 1, Chelyabinsk, Bursa } let city = City.Melbourne 

如何将city值转换为stringMelbourne ? 这种types的名字反省在语言中可用吗?

像(这个代码不会工作):

 println("Your city is \(city.magicFunction)") > Your city is Melbourne 

从Xcode 7 beta 5开始,现在可以使用print(_:)来打印types名称和枚举情况,或者使用Stringinit(_:)初始值设定项或string插值语法将其转换为String 。 所以对于你的例子:

 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" 

所以不再需要定义和维护一个方便的函数来打开每个case来返回一个string。 另外,即使没有指定原始值types,它也会自动适用于任何枚举。

debugPrint(_:)String(reflecting:)可用于完全限定的名称:

 debugPrint(city) // prints "App.City.Melbourne" (or similar, depending on the full scope) let cityDebugName = String(reflecting: city) // cityDebugName contains "App.City.Melbourne" 

请注意,您可以自定义在以下每种情况下打印的内容:

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

(我还没有find调用这个“默认”值的方法,例如,打印“城市是墨尔本”,而不debugDescription switch语句。在description / debugDescription的实现中使用\(self)会导致无限recursion)。

上面的注释Stringinit(_:)init(reflecting:)初始化符准确地描述了打印的内容,取决于reflectiontypes的符合情况:

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

有关此更改的信息,请参阅发行说明 。

目前没有对枚举个案的反省。 您将不得不手动声明它们:

 enum City : String, Printable { case Melbourne = "Melbourne" case Chelyabinsk = "Chelyabinsk" case Bursa = "Bursa" var description : String { get { return self.rawValue } } } 

注意Printable协议当前不在Playgrounds中工作。 如果你想在操场上看到string,你必须手动调用toRaw()

如果您需要原始types为Int,则必须自己进行切换:

 enum City : Int, Printable { case Melbourne = 1, Chelyabinsk, Bursa var description : String { get { switch(self) { case Melbourne: return "Melbourne" case Chelyabinsk: return "Chelyabinsk" case Bursa: return "Bursa" } } } } 

在Swift-3中(用XCode 8.1testing),你可以在你的枚举中添加下面的方法:

 /** * The name of the enumeration (as written in case). */ var name: String { get { return String(describing: self) } } /** * The full name of the enumeration * (the name of the enum plus dot plus the name as written in case). */ var description: String { get { return String(reflecting: self) } } 

然后,您可以将其用作枚举实例上的常规方法调用。 它也可能在以前的Swift版本中工作,但是我没有testing它。

在你的例子中:

 enum City: Int { case Melbourne = 1, Chelyabinsk, Bursa var name: String { get { return String(describing: self) } } var description: String { get { return String(reflecting: self) } } } let city = City.Melbourne print(city.name) // prints "Melbourne" print(city.description) // prints "City.Melbourne" 

如果要为所有枚举提供此function,可以将其扩展为:

 /** * Extend all enums with a simple method to derive their names. */ extension RawRepresentable where RawValue: Any { /** * The name of the enumeration (as written in case). */ var name: String { get { return String(describing: self) } } /** * The full name of the enumeration * (the name of the enum plus dot plus the name as written in case). */ var description: String { get { return String(reflecting: self) } } } 

这只适用于Swift枚举。

这太令人失望了。

对于你需要这些名字的情况(编译器完全知道拼写的确切内容,但是拒绝访问 – 谢谢你Swift团队!!)但是不想或者不能让String成为你枚举的基础,详细,繁琐的替代方法如下:

 enum ViewType : Int, Printable { case Title case Buttons case View static let all = [Title, Buttons, View] static let strings = ["Title", "Buttons", "View"] func string() -> String { return ViewType.strings[self.rawValue] } var description:String { get { return string() } } } 

你可以使用上面的如下:

 let elementType = ViewType.Title let column = Column.Collections let row = 0 println("fetching element \(elementType), column: \(column.string()), row: \(row)") 

你会得到预期的结果(列的代码相似,但没有显示)

 fetching element Title, column: Collections, row: 0 

在上面,我已经把description属性引用回string方法,但是这是一个有趣的问题。 还要注意,所谓的staticvariables需要通过它们的封闭types的名称来限定范围,因为编译器太遗忘,并且不能单独回忆上下文…

Swift团队必须得到真正的指挥。 他们创build枚举,你不能enumerate ,你可以使用enumerate是“序列”,而不是enum

对于Objective-C enum ,目前唯一的方法似乎是,例如,用CustomStringConvertible扩展枚举,结果如下所示:

 extension UIDeviceBatteryState: CustomStringConvertible { public var description: String { switch self { case Unknown: return "Unknown" case Unplugged: return "Unplugged" case Charging: return "Charging" case Full: return "Full" } } } 

然后以String enum

 String(UIDevice.currentDevice().batteryState) 

简单,但工程…

 enum ViewType : Int { case Title case Buttons case View } func printEnumValue(enum: ViewType) { switch enum { case .Title: println("ViewType.Title") case .Buttons: println("ViewType.Buttons") case .View: println("ViewType.View") } } 

现在Swift具有被称为隐式赋值的原始值 。 基本上,如果您不给每个案例的原始值,并且枚举types为String,则会推断出案例的原始值本身是string格式。 继续尝试。

 enum City: String { case Melbourne, Chelyabinsk, Bursa } let city = City.Melbourne.rawValue // city is "Melbourne" 

在Swift 2.2中对于enums的String(…)(CustomStringConvertible)支持之外,对它们也有一些破坏的reflection支持。 对于具有相关值的枚举案例,可以使用reflection来获取枚举案例的标签:

 enum City { case Melbourne(String) case Chelyabinsk case Bursa var label:String? { let mirror = Mirror(reflecting: self) return mirror.children.first?.label } } print(City.Melbourne("Foobar").label) // prints out "Melbourne" 

然而,通过破解,我意味着对于“简单的”枚举,上面的基于reflection的label计算属性只返回nil (boo-hoo)。

 print(City.Chelyabinsk.label) // prints out nil 

Swift 3之后的反思情况应该会越来越好,显然。 现在的解决scheme是String(…) ,正如其他答案中的build议:

 print(String(City.Chelyabinsk)) // prints out Cheylabinsk