Oui, mais vous devrez écrire votre propre encode(to:)
mise en œuvre, vous ne pouvez pas utiliser la fonction d'auto-généré.
struct Foo: Codable {
var string: String? = nil
var number: Int = 1
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(string, forKey: .string)
}
}
Codage d'une option directement encoder une valeur nulle, comme vous êtes à la recherche pour.
Si c'est une utilisation importante de cas pour vous, vous pouvez envisager l'ouverture d'un défaut à bugs.swift.org pour demander un nouveau OptionalEncodingStrategy
drapeau pour être ajouté sur JSONEncoder fonction des DateEncodingStrategy
, etc. (Voir ci-dessous pourquoi c'est probablement impossible à mettre en oeuvre rapide aujourd'hui, mais entrer dans le système de suivi est toujours utile Swift évolue.)
Edit: Pour Paulo questions ci-dessous, ce dépêches pour le générique de l' encode<T: Encodable>
version Optional
conforme Encodable
. Ceci est mis en œuvre dans Codable.swift de cette façon:
extension Optional : Encodable /* where Wrapped : Encodable */ {
@_inlineable // FIXME(sil-serialize-all)
public func encode(to encoder: Encoder) throws {
assertTypeIsEncodable(Wrapped.self, in: type(of: self))
var container = encoder.singleValueContainer()
switch self {
case .none: try container.encodeNil()
case .some(let wrapped): try (wrapped as! Encodable).__encode(to: &container)
}
}
}
Cette encapsule l'appel à l' encodeNil
, et je pense que laisser stdlib poignée de Options comme juste un autre Encodable est mieux que de les traiter comme un cas particulier dans notre propre encodeur et en appelant encodeNil
- mêmes.
Une autre question évidente est pourquoi il fonctionne de cette façon en premier lieu. Depuis Facultatif est Encodable, et les Encodable conformité code pour toutes les propriétés, pourquoi ne "coder toutes les propriétés à la main" travailler différemment? La réponse est que la conformité générateur comprend un cas spécial pour les Options:
// Now need to generate `try container.encode(x, forKey: .x)` for all
// existing properties. Optional properties get `encodeIfPresent`.
...
if (varType->getAnyNominal() == C.getOptionalDecl() ||
varType->getAnyNominal() == C.getImplicitlyUnwrappedOptionalDecl()) {
methodName = C.Id_encodeIfPresent;
}
Cela signifie que la modification de ce comportement nécessiterait de modifier la fonction d'auto-généré de conformité, pas JSONEncoder
(ce qui signifie aussi qu'il est probablement très difficile à faire configurable aujourd'hui Swift....)