2014-12-07 13 views
8

Czy istnieje sposób odwzorowania wartości niedosłownych, takich jak krotka słownik do wyliczenia? Poniższy kod rzuci Raw value for enum must be literal.wyliczanie wartości niedosłownych w Swift

enum FileType { 
    case VIDEO = ["name": "Video", "contentTypeMatcher": "video/"] 
    case IMAGE = ["name": "Image", "contentTypeMatcher": "image/"] 
    case AUDIO = ["name": "Audio", "contentTypeMatcher": "aduio/"] 
    case PDF = ["name": "PDF", "contentTypeMatcher":"application/pdf"] 
    case TEXT = ["name": "Text", "contentTypeMatcher": "text/"] 
    case FOLDER= ["name": "Folder", "contentTypeMatcher" :"application/x-directory"] 
    case PLAIN = ["name": "Plain", "contentTypeMatcher": ""] 
} 

To samo, gdy używam krotki:

enum FileType { 
    case VIDEO = (name: "Video", contentTypeMatcher: "video/") 
    case IMAGE = (name: "Image", contentTypeMatcher: "image/") 
    case AUDIO = (name: "Audio", contentTypeMatcher: "aduio/") 
    case PDF = (name: "PDF", contentTypeMatcher:"application/pdf") 
    case TEXT = (name: "Text", contentTypeMatcher: "text/") 
    case FOLDER = (name: "Folder", contentTypeMatcher :"application/x-directory") 
    case PLAIN = (name: "Plain", contentTypeMatcher: "") 
} 
+0

Wartości nieprzetworzone dla wyliczeń mogą być liczbami zmiennoprzecinkowymi, łańcuchami lub pojedynczymi znakami lub mogą być do nich zamienialne. – i40west

Odpowiedz

4

Odniesienie język, gdy mówimy o Enumeration Declaration, wyraźnie stwierdza, że:

typ surowej wartości muszą spełniać warunki Równoważny protokół i jeden z następujących protokołów przekształcalnych literalnie: IntegerLiteralConvertible dla literałów całkowitych, FloatingPointLiteralConvertible dla literałów zmiennopozycyjnych, StringLiteralConvertible dla literałów łańcuchowych t kapelusz zawiera dowolną liczbę znaków oraz ExtendedGraphemeClusterLiteralConvertible dla literałów łańcuchowych zawierających tylko jeden znak.

Nic innego jak literały mogą być używane jako wartości surowe.

Możliwym rozwiązaniem jest reprezentują słownika jako ciąg - na przykład, można oddzielić elementy z przecinkami, a klucz od wartości z dwukropkiem:

enum FileType : String { 
    case VIDEO = "name:Video,contentTypeMatcher:video/" 
    case IMAGE = "name:Image,contentTypeMatcher:image/" 
    ... 
} 

Następnie, wykorzystując właściwość komputerowej (lub metoda jeśli wolisz), zrekonstruuj słownik:

4

@Antonio daje obejście, ale nie odpowiada na faktyczne pytanie.

Określ swoje wyliczenie.

enum FileType { 

    case Image, Video 
} 

Daj przypadkach wartości nie dosłowne, niezależnie od typu, które mają ze zgodnym z protokołem RawRepresentable. Zrób to przez rozszerzenie enum, aby uzyskać czystszy kod.

extension FileType: RawRepresentable { 

    typealias Tuple = (name: String, contentTypeMatcher: String) 

    private static let allCases = [FileType.Image, .Video] 

    // MARK: RawRepresentable 

    typealias RawValue = Tuple 

    init?(rawValue: Tuple) { 

     guard let c = {() -> FileType? in 

      for iCase in FileType.allCases { 
       if rawValue == iCase.rawValue { 
        return iCase 
       } 
      } 
      return nil 

     }() else { return nil } 
     self = c 
    } 

    var rawValue: Tuple { 

     switch self { 
     case .Image: return Tuple("Image", "image/") 
     case .Video: return Tuple("Video", "video/") 
     } 
    } 
} 

Aby móc dopasować Tuple w przełączniku, należy zastosować operator dopasowywania wzorca.

private func ~= (lhs: FileType.Tuple, rhs: FileType.Tuple) -> Bool { 

    return lhs.contentTypeMatcher == rhs.contentTypeMatcher && lhs.name == rhs.name 
} 

I to wszystko ...

let a = FileType.Image 
print(a.rawValue.name) // "Image" 
let b = FileType(rawValue: a.rawValue)! 
print(a == b) // "true" 
print(b.rawValue.contentTypeMatcher) // "image/" 

Powiedzmy, że odpowiedział na pytanie bez kwestionowania. Teraz ... Enums (przynajmniej w Swift) mają unikalne przypadki. Zastrzeżenie dotyczące tego obejścia polega na tym, że możesz (mam nadzieję, że przez przypadek) zachować ten sam numer rawValue, aby uzyskać więcej przypadków. Zasadniczo Twój przykładowy kod mnie pachnie. O ile (z bardzo rozsądnego powodu) nie powinieneś stworzyć nowej wartości wyliczeniowej z krotki, zastanów się nad przeprojektowaniem. Jeśli chcesz skorzystać z tego obejścia, sugeruję (w zależności od projektu), aby zaimplementował pewne sprawdzenie, czy wszystkie wartości surowego przypadku są unikalne. Jeśli nie, należy to uwzględnić:

enum FileType { 

    case Video, Image 

    var name: String { 
     switch self { 
     case .Image: return "Image" 
     case .Video: return "Video" 
    } 

    var contentTypeMatcher: String { 
     switch self { 
     case .Image: return "image/" 
     case .Video: return "video/" 
    } 
}