如果我有一个原始整型值的枚举:
enum City: Int {
case Melbourne = 1, Chelyabinsk, Bursa
}
let city = City.Melbourne
如何将城市值转换为字符串墨尔本?这种类型名称内省在语言中可用吗?
类似于(这段代码将不起作用):
println("Your city is \(city.magicFunction)")
> Your city is Melbourne
如果我有一个原始整型值的枚举:
enum City: Int {
case Melbourne = 1, Chelyabinsk, Bursa
}
let city = City.Melbourne
如何将城市值转换为字符串墨尔本?这种类型名称内省在语言中可用吗?
类似于(这段代码将不起作用):
println("Your city is \(city.magicFunction)")
> Your city is Melbourne
当前回答
内省在快速枚举似乎部分工作。
我看到了@drewag的回复,发现一个没有rawValues的Enum确实可以在Swift 5中进行自省。X与Xcode 11.5。这段代码可以工作。
public enum Domain: String {
case network
case data
case service
case sync
var description: String {
return "\(self)" // THIS INTROSPECTION WORKS
}
}
enum ErrorCode: Int, CustomStringConvertible {
case success = 200
case created = 201
case accepted = 202
case badRequest = 400
case unauthorized = 401
case forbidden = 403
case notFound = 404
var code: Int {
return self.rawValue
}
var description: String {
return "\(self)" //THIS DOES NOT WORK - EXEC_BAD_ACCESS
}
}
let errorCode = ErrorCode.notFound
let domain = Domain.network
print(domain.description, errorCode.code, errorCode.description)
在第二个Enum中,将"\(self)"替换为"string",你将得到以下打印输出: 网络404字符串
注意:在第一个枚举中使用String(self)而不是"\(self)"将要求Enum符合theLosslessStringConvertible '协议,并添加其他初始化器,因此字符串插值似乎是一个很好的解决方案。
要将var description: String添加到枚举中,您必须使用Switch语句将前面指出的所有枚举情况
var description: String {
switch self {
case .success: return "Success"
case .created: return "Created"
case .accepted: return "Accepted"
}
}
其他回答
String(description:)初始化式可以用来返回case标签名称,即使是对于非String 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修饰符,这将不起作用:
在Swift中获取Objective-C @objc enum值的字符串名称? 为什么Enum返回“EnumName”而不是“caseLabel”的字符串(描述:)?
为Objective-C类型生成的Swift接口有时不包括@objc修饰符。这些枚举是在Objective-C中定义的,因此不像上面那样工作。
迅速:
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
内省在快速枚举似乎部分工作。
我看到了@drewag的回复,发现一个没有rawValues的Enum确实可以在Swift 5中进行自省。X与Xcode 11.5。这段代码可以工作。
public enum Domain: String {
case network
case data
case service
case sync
var description: String {
return "\(self)" // THIS INTROSPECTION WORKS
}
}
enum ErrorCode: Int, CustomStringConvertible {
case success = 200
case created = 201
case accepted = 202
case badRequest = 400
case unauthorized = 401
case forbidden = 403
case notFound = 404
var code: Int {
return self.rawValue
}
var description: String {
return "\(self)" //THIS DOES NOT WORK - EXEC_BAD_ACCESS
}
}
let errorCode = ErrorCode.notFound
let domain = Domain.network
print(domain.description, errorCode.code, errorCode.description)
在第二个Enum中,将"\(self)"替换为"string",你将得到以下打印输出: 网络404字符串
注意:在第一个枚举中使用String(self)而不是"\(self)"将要求Enum符合theLosslessStringConvertible '协议,并添加其他初始化器,因此字符串插值似乎是一个很好的解决方案。
要将var description: String添加到枚举中,您必须使用Switch语句将前面指出的所有枚举情况
var description: String {
switch self {
case .success: return "Success"
case .created: return "Created"
case .accepted: return "Accepted"
}
}
目前在枚举情况下没有自省。你必须手动声明它们:
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"
}
}
}
}
在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枚举。