2015-02-11 15 views
12

Ho una situazione in cui sto cercando di eseguire la decodifica binaria di alcuni dati e i tipi di dati hanno sia un valore numerico che un valore di stringa e un nome. Stavo pensando di utilizzare un enum come ad esempio:Swift enum sia una stringa che uno

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

Tuttavia so anche che:

TT_INVALID = 0 e TT_TRUE_TRACK_ANGLE = 1, ecc C'è un modo semplice per incapsulare entrambe queste "cose" la stringa di testo e la numerica valore in un costrutto enum o devo fare una sorta di struct/class per gestire questo?

immagino mi piacerebbe fare qualcosa di simile

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

che stampare True Track Angle

Ancora una volta, so che questo può essere fatto con una struttura o di una classe, ma io' m specificamente interessato all'enum

O per un altro esempio:

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

C'è un modo per rifattorizzare questa struttura in un enum in modo tale che io costruisca l'enum con un valore intero ma "leggo" l'enum come una stringa? Sono abbastanza sicuro che la risposta sia no.

+0

Non capisco la tua domanda, ad essere onesti. Dog.BT e Dog.BULL? 'let d = Dog (rawValue:" Bulldog ")'? –

+0

O intendi questo: http://stackoverflow.com/questions/24007461/how-to-enumerate-an-enum-with-string-type –

+0

simile ma non esattamente. – Jeef

risposta

21

Penso che questo lo farà per me. Grazie auto .. :)

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

Come si accede a questo? – binsnoel

+1

Perché creare un protocollo personalizzato? Non dovrebbe essere "CustomStringConvertible" che funzioni bene e sia più flessibile? – NobodyNada

1

Hai mai pensato di utilizzare un dizionario?

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

Nota i codici numerici non devono essere ordinati o contigui. Essere specifici sul tipo di dizionario nella sua dichiarazione impedisce un sacco di avvertimenti o errori nei seguenti frammenti.

Ottenere il nome di un codice è semplice:

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

non ho trovato un modo ordinato di ottenere il codice per un nome, ma questo lo fa:

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

e si ovviamente lo vestirebbe come una funzione. Quello che non ottieni automaticamente è un nome interno per il tuo tipo di traccia, ma ne hai bisogno? E la linea sopra lo fa per te in un certo senso.

Problemi correlati