Swift枚举字符串和int

时间:2022-03-24 16:23:30

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?

TT_INVALID = 0和TT_TRUE_TRACK_ANGLE = 1等。是否有一种简单的方法可以将字符串和数值这些“东西”封装到枚举构造中,还是需要制作某种结构/类来处理它?

I guess I'd like to do something like

我想我想做点什么

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

设a = TARGET_TRACK_TYPE.rawValue(值: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.

有没有办法将这个结构重构为一个枚举,以便我用一个整数值构造枚举,但我“读取”枚举为一个字符串?我很确定答案是否定的。

2 个解决方案

#1


26  

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

#2


1  

Have you considered using a dictionary?

你考虑过用字典吗?

 let targetTrackDict: [Int: String] =
      [99: "Invalid",
       1: "True Track Angle",
       2: "Magnetic",
       5: "True"]

Note the number codes don't have to be ordered or contiguous. Being specific about the dictionary's type in its declaration prevents a lot of warnings or errors in the following snippets.

请注意,数字代码不必排序或连续。在其声明中具体说明字典的类型可以防止以下片段中的大量警告或错误。

Getting the name for a code is easy:

获取代码的名称很简单:

var code = 2
if let name = targetTrackDict[code] {
  print("\(name) has code \(code)")
} else {
  print("\(code) is not a valid track type")
}

I haven't found a tidy way of getting the code for a name, but this does it:

我还没有找到一个获取名称代码的整洁方法,但这样做:

let magneticCode = targetTrackDict.first(where: 
    {key, value in value == "Magnetic"})?.key
// returns an optional

and you would of course dress it up as a function. What you don't get automatically is an internal name for your track type, but do you need one? And the line above does it for you in a way.

你当然会把它打扮成一个功能。你没有自动获得的是你的赛道类型的内部名称,但你需要一个吗?以上这一行在某种程度上适合你。

#1


26  

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

#2


1  

Have you considered using a dictionary?

你考虑过用字典吗?

 let targetTrackDict: [Int: String] =
      [99: "Invalid",
       1: "True Track Angle",
       2: "Magnetic",
       5: "True"]

Note the number codes don't have to be ordered or contiguous. Being specific about the dictionary's type in its declaration prevents a lot of warnings or errors in the following snippets.

请注意,数字代码不必排序或连续。在其声明中具体说明字典的类型可以防止以下片段中的大量警告或错误。

Getting the name for a code is easy:

获取代码的名称很简单:

var code = 2
if let name = targetTrackDict[code] {
  print("\(name) has code \(code)")
} else {
  print("\(code) is not a valid track type")
}

I haven't found a tidy way of getting the code for a name, but this does it:

我还没有找到一个获取名称代码的整洁方法,但这样做:

let magneticCode = targetTrackDict.first(where: 
    {key, value in value == "Magnetic"})?.key
// returns an optional

and you would of course dress it up as a function. What you don't get automatically is an internal name for your track type, but do you need one? And the line above does it for you in a way.

你当然会把它打扮成一个功能。你没有自动获得的是你的赛道类型的内部名称,但你需要一个吗?以上这一行在某种程度上适合你。