How to get the name of enumeration value in Swift?

前端 未结 12 1372
太阳男子
太阳男子 2020-11-29 23:53

If I have an enumeration with raw Integer values:

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

let city = City.Melbourne
         


        
相关标签:
12条回答
  • 2020-11-30 00:47

    For Objective-C enums the only way currently seems to be, for example, to extend the enum with CustomStringConvertible ending up with something like:

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

    And then casting the enum as String:

    String(UIDevice.currentDevice().batteryState)
    
    0 讨论(0)
  • 2020-11-30 00:53

    In Swift-3 (tested with Xcode 8.1) you can add the following methods in your enum:

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

    You can then use it as a normal method call on your enum instance. It might also work in previous Swift versions, but I haven't tested it.

    In your example:

    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"
    

    If you want to provide this functionality to all your enums, you can make it an extension:

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

    This only works for Swift enums.

    0 讨论(0)
  • 2020-11-30 00:55

    This is so disappointing.

    For the case when you need those names (that the compiler perfectly knows the exact spelling of, but refuses to let access -- thank you Swift team!! --) but do not want or cannot make String the base of your enum, a verbose, cumbersome alternative is as follows:

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

    You can use the above as follows:

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

    And you'll get the expected result (code for the Column similar, but not shown)

    fetching element Title, column: Collections, row: 0
    

    In the above, I have made the description property refer back to the string method, but this is a matter of taste. Also note that so called static variables need to be scope qualified by the name of their enclosing type, as the compiler is too amnesic and cannot recall the context all by itself...

    The Swift team must really be commanded. They created enum that you cannot enumerate and that which you can use enumerate on are "Sequences" but not enum!

    0 讨论(0)
  • 2020-11-30 00:55

    I bumped into this question and wanted to share a simple way to create the magicFunction mentioned

    enum City: Int {
      case Melbourne = 1, Chelyabinsk, Bursa
    
        func magicFunction() -> String {
            return "\(self)"
        }
    }
    
    let city = City.Melbourne
    city.magicFunction() //prints Melbourne
    
    0 讨论(0)
  • 2020-11-30 00:56

    Simple but works...

    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")
        }
    }
    
    0 讨论(0)
  • 2020-11-30 00:57

    There is no introspection on enum cases at the moment. You will have to declare them each manually:

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

    If you need the raw type to be an Int, you will have to do a switch yourself:

    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"
          }
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题