2017-12-20 18 views
2

Ich habe eine Enumeration wie folgt definiert:Dekodierbare, nicht dekodieren nicht optional Enum mit ungültigem Wert

enum ClubLevel: Int, Codable { 
    case golden = 1, silver, bronze 
} 

in meinem struct Ich habe eine optionale Eigenschaft des Typs ClubLevel und wenn ich dekodieren diese Eigenschaft in init(from decoder: Decoder):

self.clubLevel = try container.decode(ClubLevel?.self, forKey: .clubLevel) 

ich stehe diesen Fehler:

debugdescription: "Cannot initialize ClubLevel from invalid Int value 0", underlyingError: nil"

Ich frage mich, auch diese Eigenschaft ist optional, Decoder wird nicht fortgesetzt

keine Idee?

+0

danke für Ihren Kommentar @hamish können Sie erklären, was Unterschied zwischen 'versuchen? container.decode (ClubLevel.self, forKey: .clubLevel) 'und' try container.decode (ClubLevel? .self, forKey: .clubLevel) '. Sie können Ihren Kommentar als Antwort –

Antwort

2

Die Linie

self.clubLevel = try container.decode(ClubLevel?.self, forKey: .clubLevel) 

versucht nicht ClubLevel zu dekodieren, nil wenn nicht erfolgreich zuweisen. Was sie tut, ist:

  1. Try nil (dargestellt in JSON als null) für die clubLevel Schlüssel zu entschlüsseln. Wenn nicht erfolgreich,
  2. Versuchen Sie, einen ClubLevel für den Schlüssel clubLevel zu decodieren. Wenn dies nicht erfolgreich,
  3. Werfen Sie einen Fehler

Also, wenn der Wert für die clubLevel Schlüssel ist weder nil noch eine gültige ClubLevel Darstellung, werden Sie einen Fehler geworfen. Sie werden feststellen, dass dies auch bedeutet, dass Sie eine Fehlermeldung erhalten, wenn der Schlüssel clubLevel vollständig fehlt (anstatt mit einem Wert von nil vorhanden zu sein).

fehlende Schlüssel Ignoriert wird mit decodeIfPresent getan:

self.clubLevel = try container.decodeIfPresent(ClubLevel.self, forKey: .clubLevel) 

Dies wird nun:

  1. Return nil wenn die clubLevel Schlüssel aus dem Behälter fehlen. Wenn der Schlüssel vorhanden ist,
  2. Versuchen Sie, nil (in JSON als null dargestellt) für den Schlüssel clubLevel zu decodieren. Wenn nicht erfolgreich,
  3. Versuchen Sie, einen ClubLevel für den Schlüssel clubLevel zu decodieren. Wenn dies nicht erfolgreich,
  4. Werfen Sie einen Fehler

Dies ist das Standardverhalten für die Decodierung optionals in einem Compiler generierte Implementierung von init(from:). Es wird immer noch einen Fehler in Ihrem Fall auslösen, da der Wert für den Schlüssel clubLevel kein gültiger ClubLevel ist.

Wenn Sie wollen einfach nur versuchen, ein ClubLevel zu dekodieren, nil auf dem Dekodierung Zuweisung für jeden Grund (Schlüssel fehlt, ungültigen Wert andernfalls, usw.), dann möchten Sie verwenden try?:

self.clubLevel = try? container.decode(ClubLevel.self, forKey: .clubLevel) 
+0

Dank für detaillierte Antwort! Fröhliche Weihnachten –

Verwandte Themen