2015-04-22 16 views
9

La domanda rapida è un modo per avere un tipo enum con un caso che può avere un valore associato.Come devo implementare i valori associati predefiniti con Swift Enums?

Ho un'API che mi fornisce i filtri disponibili, è improbabile ma possibile che l'API aggiungerà ulteriori tipi di filtro. Quindi se l'API invia un tipo di filtro sconosciuto, voglio mantenere quell'informazione associata all'enum.

Di seguito sono le diverse idee che ho avuto su questo.

Le mie prime due prove non sono state compilate. Il mio terzo tentativo mi sembra un po 'goffo.

Qualcuno ha un modo migliore di farlo? Pensi che non dovrei usare un enum per questo problema?

typealias APIFilterIdentifier = String 

/* Does Not Compile */ 
enum EnumTestAssociatedValeu: APIFilterIdentifier { 
    case Unknown(APIFilterIdentifier) 
    case Everyone = "everyone" 
    case Team = "myteam" 
} 

/* Does not compile */ 
enum EnumTestDefaultAssociatedValues: APIFilterIdentifier { 
    case Unknown(APIFilterIdentifier) 
    case Everyone(APIFilterIdentifier = "everyone") 
    case Team(APIFilterIdentifier = "myteam") 
} 

/* Compiles but is there a better way? */ 
enum EnumTestWithCustomInit { 

    case Unknown(APIFilterIdentifier) 
    case Everyone 
    case Team 

    init(filterIdentifier: APIFilterIdentifier) { 
     let everyone: APIFilterIdentifier = EnumTestWithCustomInit.everyoneFilterIdentifier 
     let team: APIFilterIdentifier = EnumTestWithCustomInit.teamFilterIdentifier 

     switch filterIdentifier { 
     case everyone: 
      self = .Everyone 
     case team: 
      self = .Team 
     default: 
      self = .Unknown(filterIdentifier) 
     } 
    } 

    func asIdentifer() -> APIFilterIdentifier { 
     switch self { 
     case .Everyone: 
      return EnumTestWithCustomInit.everyoneFilterIdentifier 
     case .Team: 
      return EnumTestWithCustomInit.teamFilterIdentifier 
     case .Unknown(let filterIdentifier): 
      return filterIdentifier 
     } 
    } 

    private static var everyoneFilterIdentifier: APIFilterIdentifier { 
     return "everyone" 
    } 

    private static var teamFilterIdentifier: APIFilterIdentifier { 
     return "myteam" 
    } 
} 
+1

Mi piacerebbe se qualcuno potesse fare un titolo migliore per questa domanda. – Tobias

+0

Ho la stessa domanda Come implementare valori associati predefiniti con Swift Enums? Hai trovato una risposta? Grazie – Mariam

+2

@Mariam Non è possibile in Swift 1.2. – Tobias

risposta

8

So che questo è un po 'vecchio, ma questo funziona per quello che vuoi?

typealias FilterIdentifier = String 

enum DefaultAPIFilters: FilterIdentifier { 
    case Everyone = "everyone" 
    case Team = "team" 
} 

enum APIFilters { 
    case Default(DefaultAPIFilters) 
    case Custom(FilterIdentifier) 
} 

let everyoneFilter = APIFilters.Default(.Everyone) 
let teamFilter = APIFilters.Default(.Team) 
let clownFilter = APIFilters.Custom("clowns_only") 
+0

Come si ottiene il valore sottostante da questo costrutto? Ad esempio, per ottenere la stringa per manipolazione arbitraria – SG1

+0

mi piace questo metodo. Penso che potrei rendere DefaultAPIFilters un enum interiore. – Tobias

+0

Qual è il valore associato di default? –

4

Estendere la risposta di Nathan Perry:

È possibile aggiungere un

var underlyingString: String { 
    return getUnderlyingString(self) 
} 

al enum. Quindi definire

func getUnderlyingString(apiFilter: APIFilters) -> String { 
    switch apiFilter { 
    case .Default(let defaultAPIFilter): 
     return defaultAPIFilter.rawValue 
    case .Custom(let custom): 
     return custom 
    } 
} 
Problemi correlati