2014-10-15 20 views
39

Czy możliwe jest utworzenie wyliczenia krotek w Swift?Enum krotek w Swift

Chciałbym zbudować coś takiego:

enum ErrorCode: (Int, String) { 
    case Generic_Error = (0, "Unknown") 
    case DB_Error = (909, "Database") 
} 

Ale to nie kompiluje ... Czy istnieje sposób, aby uzyskać podobny wynik?

+2

Ktoś wie, dlaczego nie jest to dozwolone w Swift? – agy

+0

możesz podać swój enum inicjator dla wyliczenia, który dostanie krotkę i zainicjalizujesz skrzynkę, której potrzebujesz. Może tego właśnie potrzebujesz ... A potem możesz po prostu zadzwonić do MyCustomEnum (tuple: (1, "myString")) i to zadziała. A wewnątrz enum inicjalizatora możesz użyć Swiftsa pasującego do switcha, aby zrobić cokolwiek, czego potrzebujesz. – Fawkes

Odpowiedz

33

Zależy od tego, co masz na myśli przez "podobny". Co mogę zrobić, to użyć struct z właściwości statycznych stałych:

struct Trouble { 
    static let Generic_Error = (0, "Unknown") 
    static let DB_Error = (909, "Database") 
} 

Teraz takie rzeczy Trouble.Generic_Error są użyteczne w całym kodzie.

14

można zrobić coś takiego, może:

enum ErrorCode { 
    case Generic_Error 
    case DB_Error 

    func values() -> (code: Int!, description: String?)! { 
     switch self { 
     case .Generic_Error: 
      return (0, "Unknown") 
     case .DB_Error: 
      return (909, "Database") 
     } 
    } 
} 

i można zrobić coś takiego później:

let errorCode: ErrorCode = ErrorCode.Generic_Error; 
if (errorCode.values().code == 0) { 
    // do the business here... 
} 
42

Swift wyliczenia nie można mieć krotek jako typ wartości surowca.

Alternatywne rozwiązania obejmują przechowywania kodu i wynikające z opisu, że:

enum ErrorCode: Int, CustomStringConvertible { 
    case Generic = 0 
    case DB = 909 

    var description: String { 
     switch self { 
     case .Generic: 
      return "Unknown" 
     case .DB: 
      return "Database" 
     } 
    } 
} 

... lub przechowywania wartości skojarzone z kodem i opisem w przypadkach wyliczeniowych się:

enum Error { 
    case Generic(Int, String) 
    case DB(Int, String) 
} 

Jeśli "Po prostu szukamy stałych wartości, tak samo działałaby sugestia @ matt dotycząca organizacji ich w ramach struct.

+0

Nazwa pliku do wydruku zmienia się na CustomStringConvertible – Forke

+0

W jaki sposób użyłbym 'Error' powyżej? – capikaw

+0

O tak, możesz umieścić metody (i tylko do odczytu vars) na samym enum. Fajnie ... dzięki! –

-3
+0

Łącze pokazuje przykład rozwiązania tego problemu, ale nie jest tak proste jak "Utwórz wyliczenie jako Int". Jest to w zasadzie odpowiednik pierwszego przykładu kodu @ mattta, ale opiera się na NSHTTPURLResponse.localizedStringForStatusCode dla opisu zamiast przełączania siebie. Powinieneś edytować swoją odpowiedź z tymi szczegółami. – Marmoy

6

Rozwiązanie podobne do @holex, ale zamiast funkcji można użyć var.

enum SomeType { 
    case type1 
    case type2 
    case type3 

    var typeNameAndDescription: (name: String, description: String) { 
     switch self { 
     case .type1: 
      return ("type1 name", "type1 description") 
     case .type2: 
      return ("type2 name", "type2 description") 
     case .type3: 
      return ("type3 name", "type3 description") 
     } 
    } 
} 

i później:

let myType = SomeType.type1 
let typeName = myType.typeNameAndDescription.name 
let typeDescription = myType.typeNameAndDescription.description 
5

Możesz odpowiadać RawRepresentable i używać (Int, String) jako Self.RawValue powiązanego typu.

enum ErrorCode: RawRepresentable { 
    case Generic_Error 
    case DB_Error 

    var rawValue: (Int, String) { 
     switch self { 
     case .Generic_Error: return (0, "Unknown") 
     case .DB_Error: return (909, "Database") 
     } 
    } 

    init?(rawValue: (Int, String)) { 
     switch rawValue { 
     case (0, "Unknown"): self = .Generic_Error 
     case (909, "Database"): self = .DB_Error 
     default: return nil 
     } 
    } 
}