If I have an enumeration with raw Integer values:

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

let city = City.Melbourne

How can I convert a city value to a string Melbourne? Is this kind of a type name introspection available in the language?

Something like (this code will not work):

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

推荐答案

As of Xcode 7 beta 5 (Swift version 2) you can now print type names and enum cases by default using print(_:), or convert to String using String's init(_:) initializer or string interpolation syntax. So for your example:

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"

So there is no longer a need to define & maintain a convenience function that switches on each case to return a string literal. In addition, this works automatically for any enum, even if no raw-value type is specified.

debugPrint(_:) & String(reflecting:) can be used for a fully-qualified name:

debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)

let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"

Note that you can customise what is printed in each of these scenarios:

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

(I haven't found a way to call into this "default" value, for example, to print "The city is Melbourne" without resorting back to a switch statement. Using \(self) in the implementation of description/debugDescription causes an infinite recursion.)


The comments above String's init(_:) & init(reflecting:) initializers describe exactly what is printed, depending on what the reflected type conforms to:

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


See the release notes for info about this change.

Swift相关问答推荐

避免嵌套导航TabView

是否可以循环遍历SWIFT子类并访问它们的静态变量S?

为什么ClosedRange<;Int&>包含的速度比预期慢340万倍?

从任务中打印

NavigationLink和ObservableObject的动画片段

对实例方法appendInterpolation的调用没有完全匹配

SwiftUI 拖放:如果没有上下文类型,则无法解析对成员‘first’的引用

应该在ViewModel还是ViewController中使用"Task {}"?

URL appendPathComponent(_:) 已弃用?

如何为等待函数调用添加超时

如何测试可选 struct 的协议一致性

将内容与工作表顶部而不是中间对齐

当我必须在 Swift 中的类、 struct 和枚举之间进行 Select 时,我应该如何推理?

不支持用作符合协议 AnyObject 的具体类型

FCM 后台通知在 iOS 中不起作用

Swift 动画 WithDuration 语法是什么?

将活动指示器 colored颜色 更改为黑色

两个 Date 对象之间的所有日期 (Swift)

在 Swift 中指定 UITextField 的边框半径

使用 swift 更新到 Xcode 6 beta 4 后获取 dyld_fatal_error