Подтвердить что ты не робот

Swift перечисляет как строку, так и int

У меня есть ситуация, когда я пытаюсь выполнить двоичное декодирование некоторых данных, а типы данных имеют как числовое значение, так и строковое значение и имя. Я думал об использовании перечисления, например:

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

Однако я также знаю, что:

TT_INVALID = 0 и TT_TRUE_TRACK_ANGLE = 1 и т.д. Есть ли простой способ инкапсулировать обе эти "вещи" строку и числовое значение в конструкцию enum или мне нужно сделать какой-то тип struct/class для обработки этого

Думаю, я хотел бы сделать что-то вроде

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

который печатает True Track Angle

Опять же, я знаю, что это можно сделать с помощью структуры или класса, но меня особенно интересует перечисление

Или для другого примера:

/// 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)";
    }
}
}

Есть ли способ реорганизовать эту структуру в enum, чтобы я построил перечисление с целым значением, но я "прочитал" перечисление как строку? Я уверен, что ответа нет.

4b9b3361

Ответ 1

Я думаю, что это сделает это для меня. Спасибо...)

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

В Swift 4.2 это можно сделать с помощью CaseIterable. Одним из относительно кратких способов является следующее

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"

Ответ 3

Рассматривали ли вы использование словаря?

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

Обратите внимание, что числовые коды не должны быть упорядоченными или непрерывными. Специфичность типа словаря в его объявлении предотвращает множество предупреждений или ошибок в следующих фрагментах.

Получение имени для кода очень просто:

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

Я не нашел опрятный способ получить код для имени, но он делает это:

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

и вы, конечно, нарядите его как функцию. То, что вы не получаете автоматически, является внутренним именем для вашего типа трека, но вам он нужен? И линия выше делает это для вас в некотором роде.

Ответ 4

Вы должны использовать RawRepresentable

@objc enum AppEvent:Int, RawRepresentable  {
    case appLaunch
    case homeScreen

    public typealias RawValue = String

    public var rawValue: RawValue {
        switch self {
        case .appLaunch                      : return "appLaunch"
        case .homeScreen                    : return "homeScreen"
    }

    public init?(rawValue: RawValue) {
        switch rawValue {
        case "appLaunch"                    : self = .appLaunch
        case "homeScreen"                   : self = .homeScreen 
    }