Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift enum both a string and an int

Tags:

enums

swift

I have a situation where I'm trying to do binary decoding of some data and the data types have both a numerical value and a string value and a name. I was thinking of using an enum such as:

enum TARGET_TRACK_TYPE : String {     case TT_INVALID          = "Invalid"     case TT_TRUE_TRACK_ANGLE = "True Track Angle"     case TT_MAGNETIC         = "Magnetic"     case TT_TRUE             = "True" } 

However I also know that:

TT_INVALID = 0 and TT_TRUE_TRACK_ANGLE = 1, etc. Is there an easy way to encapsulate both these "things" the string and the numerical value into an enum construct or do i need to make some sort of struct/class to handle this?

I guess I'd like to do something like

let a = TARGET_TRACK_TYPE.rawValue(value: 2) println(a)

which would print True Track Angle

Again, I know this can be done with a struct or a class but I'm specifically interested in the enum

Or for another example:

/// Emitter Category is defined in section 3.5.1.10 of the GDL90 Spec struct EmitterCategory {  let category : Int  func getString() -> String {      switch(category) {     case 0:         return "No aircraft type information";     case 1:         return "Light";     case 2:         return "Smalle";     case 3:         return "Large";     case 4:         return "High Vortex Large";     case 5:         return "Heavy";     case 6:         return "Highly Manuverable";     case 7:         return "Rotorcraft";     case 8:         return "(Unassigned)";     case 9:         return "Glider/sailplane";     case 10:         return "Ligther than air";     case 11:         return "Parachutist/sky diver";     case 12:         return "Ultra light/hang glider/paraglider";     case 13:         return "(Unassigned)";     case 14:         return "Unmanned aerial vehicle";     case 15:         return "Space/transatmospheric vehicle";     case 16:         return "(Unassigned)";     case 17:         return "Surface vehicle - emergency vehicle";     case 18:         return "Surface vehicle - service vehicle";     case 19:         return "Point obstacle";     case 20:         return "Cluster Obstacle";     case 21:         return "Line Obstacle";     default:         return "(reserved)";     } } } 

Is there a way to refactor this struct into an enum such that I construct the enum with an integer value but I "read" the enum as a string? I'm pretty sure the answer is no.

like image 623
Jeef Avatar asked Feb 11 '15 17:02

Jeef


People also ask

Can associated values and raw values coexist in Swift enumeration?

A Swift enum can either have raw values or associated values.

Is enum string or int?

The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.

How does enum work in Swift?

Enumerations (or enums for short) in Swift define a common type for a group of related values. According to the Swift documentation, enums enable you to work with those values in a type-safe way within your code. Enums come in particularly handy when you have a lot of different options you want to encode.

Can a Swift enum have functions?

Cases as functions Finally, let's take a look at how enum cases relate to functions, and how Swift 5.3 brings a new feature that lets us combine protocols with enums in brand new ways. A really interesting aspect of enum cases with associated values is that they can actually be used directly as functions.


2 Answers

I think this will do it for me. Thank you self.. :)

protocol GDL90_Enum  {       var description: String { get } }  enum TARGET_ADDRESS_TYPE : Int, GDL90_Enum {    case ADSB_ICAO_ADDRESS = 0    case ADSB_SELF_ADDRESS = 1    case TISB_ICAO = 2    case TISB_TRACK_ID = 3    case SURFACE_VEHICLE = 4    case GROUND_STATION = 5     var description: String {       switch self {    case .ADSB_ICAO_ADDRESS:       return "ADS-B with ICAO address"    case .ADSB_SELF_ADDRESS:       return "ADS-B with Self-assigned address"    case .TISB_ICAO:       return "TIS-B with ICAO address"    case .TISB_TRACK_ID:          return "TIS-B with track file ID"    case .SURFACE_VEHICLE:          return "Surface Vehicle"    case .GROUND_STATION:          return "Ground Station Beacon"    default:          return "Reserved"       }    } } 
like image 108
Jeef Avatar answered Sep 25 '22 05:09

Jeef


With Swift 4.2 this can be done using CaseIterable. One, relatively concise way is to do the following

enum Directions: String, CaseIterable {     case north, south, east, west      static var asArray: [Directions] {return self.allCases}      func asInt() -> Int {         return Directions.asArray.firstIndex(of: self)!     } }  print(Directions.asArray[2]) // prints "east\n"  print(Directions.east.asInt()) // prints "2\n"  print(Directions.east.rawValue) // prints "east\n" 
like image 39
Jonathan Bronson Avatar answered Sep 24 '22 05:09

Jonathan Bronson