如果我有一个原始整型值的枚举:

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

其他回答

在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枚举。

我遇到了这个问题,想分享一个创建magicFunction的简单方法

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

    func magicFunction() -> String {
        return "\(self)"
    }
}

let city = City.Melbourne
city.magicFunction() //prints Melbourne

对于Objective-C枚举来说,目前唯一的方法似乎是,例如,用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:

String(UIDevice.currentDevice().batteryState)

迅速:

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

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中定义的,因此不像上面那样工作。