Answers:
从Xcode 7 beta 5(Swift版本2)开始,您现在可以默认使用来打印类型名称和枚举大小写print(_:)
,或者String
使用String
的init(_:)
初始值设定项或字符串插值语法将其转换为。因此,对于您的示例:
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"
因此,不再需要定义和维护一个便捷函数,该函数在每种情况下都可以打开以返回字符串文字。此外,即使未指定原始值类型,此方法也可自动用于任何枚举。
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)"
(我还没有找到一种方法来调用此“默认”值,例如,在不诉诸switch语句的情况下打印“城市是墨尔本”。\(self)
在description
/ 的实现中使用debugDescription
会导致无限递归。)
上面String
的init(_:)
&init(reflecting:)
初始值设定项中的注释确切描述了打印的内容,具体取决于所反映的类型符合以下条件:
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)
}
有关此更改的信息,
请参见发行说明。
CLAuthorizationStatus
在locationManager didChangeAuthorizationStatus
委托回调中打印(Objective C)枚举的值,则需要定义协议扩展。例如:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
-完成此操作后,它应会按预期工作:print(“ Auth status:(\ status))”。
目前没有对枚举案例的自省。您将必须分别手动声明它们:
enum City: String, CustomStringConvertible {
case Melbourne = "Melbourne"
case Chelyabinsk = "Chelyabinsk"
case Bursa = "Bursa"
var description: String {
get {
return self.rawValue
}
}
}
如果您需要将原始类型设为Int,则必须自己进行切换:
enum City: Int, CustomStringConvertible {
case Melbourne = 1, Chelyabinsk, Bursa
var description: String {
get {
switch self {
case .Melbourne:
return "Melbourne"
case .Chelyabinsk:
return "Chelyabinsk"
case .Bursa:
return "Bursa"
}
}
}
}
get { ... }
如果您未定义设置器,也可以为简洁起见省略该部分。
enum City : String, CustomStringConvertible {
。作为CSC协议的一部分,您然后需要将属性更改为public,例如:public var description : String {
在Swift-3(经过Xcode 8.1测试)中,您可以在枚举中添加以下方法:
/**
* 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版本中使用,但我尚未对其进行测试。
在您的示例中:
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"
如果要为所有枚举提供此功能,则可以将其扩展:
/**
* 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枚举。
对于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"
}
}
}
然后将enum
as 转换为String
:
String(UIDevice.currentDevice().batteryState)
该String(describing:)
初始化可以用来甚至对于非字符串rawValues枚举返回的情况下的标签名称:
enum Numbers: Int {
case one = 1
case two = 2
}
let one = String(describing: Numbers.one) // "one"
let two = String(describing: Numbers.two) // "two"
请注意,这不工作,如果枚举使用@objc
修饰符:
为Objective-C类型生成的Swift接口有时不包含@objc
修饰符。但是,这些Enum是在Objective-C中定义的,因此不能像上面那样工作。
除了对Swift 2.2中的枚举的String(...)(CustomStringConvertible)支持之外,对它们的反射支持也有所中断。对于具有关联值的枚举案例,可以使用反射来获取枚举案例的标签:
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"
但是,通过破坏,我的意思是对于“简单”枚举,上述基于反射的label
计算属性只返回nil
(boo-hoo)。
print(City.Chelyabinsk.label) // prints out nil
显然,在Swift 3之后,反射的情况应该会变得更好。不过String(…)
,目前的解决方案是,如其他答案之一所示:
print(String(City.Chelyabinsk)) // prints out Cheylabinsk
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
真令人失望。
对于这种情况,当您需要这些名称(编译器完全知道其确切拼写,但拒绝让其访问-谢谢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)")
您将获得预期的结果(类似于Column的代码,但未显示)
fetching element Title, column: Collections, row: 0
在上面,我做了 description
属性重新引用该string
方法,但这只是一个问题。还请注意,所谓的static
变量需要通过其封闭类型的名称来限定范围,因为编译器过于健忘并且无法单独调用所有上下文...
斯威夫特团队必须真正受到指挥。他们创建了您无法enumerate
使用的枚举,并且您可以使用的枚举enumerate
是“序列”,但不是enum
!
对于Swift:
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"
}
}
}
如果您的变量“ batteryState”,则调用:
self.batteryState.description
简单但可行...
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")
}
}
print(enum)
可以使用String(enum)