Taking your code as an example: Swift Swift struct Foo : Codable { var prop1: Int? var prop2: Int? enum CodingKeys { ... } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) prop1 = try container.decodeIfPresent(Int.self, forKey: .prop1) prop2 = try container.decode(Int?.self, forKey: .prop2) } func encode(to encoder: Encoder) throws { ... } }
try decoder.decode(Foo.self, from: "{ \"prop1\": 42, \"prop2\": 99 }".data(using: .utf8)!) // => prop1 == Optional(42), prop2 == Optional(99) try decoder.decode(Foo.self, from: "{ \"prop1\": null, \"prop2\": 99 }".data(using: .utf8)!) // => prop1 == nil, prop2 == Optional(99) try decoder.decode(Foo.self, from: "{ \"prop1\": 42, \"prop2\": null }".data(using: .utf8)!) // => prop1 == Optional(42), prop2 == nil try decoder.decode(Foo.self, from: "{ \"prop2\": 99 }".data(using: .utf8)!) // => prop1 == nil, prop2 == Optional(99) try decoder.decode(Foo.self, from: "{ \"prop1\": 42 }".data(using: .utf8)!) // => error, .keyNotFound (key "prop2" is missing) decode<T>(_:forKey:) always expects the key to be there; if T == Optional<U> then the value may be null, but the entry must be present, since that’s what you’re asserting. decodeIfPresent<T>(_:forKey:) will return nil if the key is not present, or if T == Optional<U> and the value is null. (This, BTW, is not a change in semantics from how things work today.) > On Jun 26, 2017, at 1:03 PM, David Hart <da...@hartbit.com> wrote: > > What I still have difficulties understanding is what will be the semantic > difference between decodeIfPresent and decode with optional type: > > func init(from decoder: Decoder) throws { > let container = try decoder.container(keyedBy: CodingKeys.self) > prop1 = try container.decodeIfPresent(Prop1Type.self, forKey: .prop1) > prop2 = try container.decode(Optional<Prop2Type>.self, forKey: .prop2) > } > >> On 26 Jun 2017, at 19:10, Itai Ferber <ifer...@apple.com >> <mailto:ifer...@apple.com>> wrote: >> >> Reply-all this time too. :) >> Thanks for the feedback, David! >> >> encodeIfPresent and decodeIfPresent are not strictly necessary, but they’re >> useful for further cutting down boilerplate. encodeIfPresent is equivalent to >> >> if let value = value { >> try container.encode(value, forKey: .someKey) >> } >> and decodeIfPresent is equivalent to >> >> if container.contains(.someKey) { >> value = try container.decode(Value.self, forKey: .someKey) >> } else { >> value = nil >> } >> They’re not big, but when you have a long list of optional properties, it’s >> much easier to read and comprehend than staring at a wall of Optional >> wrapping/unwrapping: >> >> func init(from decoder: Decoder) throws { >> let container = try decoder.container(keyedBy: CodingKeys.self) >> >> if container.contains(.prop1) { >> prop1 = try container.decode(Prop1Type.self, forKey: .prop1) >> } else { >> prop1 = nil >> } >> >> if container.contains(.prop2) { >> prop2 = try container.decode(Prop2Type.self, forKey: .prop2) >> } else { >> prop2 = nil >> } >> >> if container.contains(.prop3) { >> prop3 = try container.decode(Prop3Type.self, forKey: .prop3) >> } else { >> prop3 = nil >> } >> } >> >> // vs. >> >> func init(from decoder: Decoder) throws { >> let container = try decoder.container(keyedBy: CodingKeys.self) >> prop1 = try container.decodeIfPresent(Prop1Type.self, forKey: .prop1) >> prop2 = try container.decodeIfPresent(Prop2Type.self, forKey: .prop2) >> prop3 = try container.decodeIfPresent(Prop3Type.self, forKey: .prop3) >> } >> On 23 Jun 2017, at 13:52, David Hart wrote: >> >> There are a lot of great changes here which make sense after the fact. I'll >> try to play around with them. >> >> One thing I'm concerned about: with the new Optional conformance, why do we >> still need decodeIfPresent and encodeIfPresent? They seem superfluous now, >> and potentially confusing. Should users call encodeIfPresent/decodeIfPresent >> or encode/decode with an optional type? Do the have the same semantics? >> >> On 23 Jun 2017, at 21:47, Itai Ferber via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >>> Hi swift-evolution, >>> >>> Over the course of the past few weeks, we’ve been gathering feedback about >>> the outcome of SE-0166 >>> <https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md> >>> and SE-0167 >>> <https://github.com/apple/swift-evolution/blob/master/proposals/0167-swift-encoders.md> >>> (both internally and externally), and we gathered a collection of updates >>> that we’re going to introduce to the proposals and to the implementation. >>> >>> Attached is rendered HTML (I don’t want to make your mail clients unusable >>> like last time!) that lays out what we’d like to do. We’re not looking to >>> do a full review of these changes, but if you have feedback or questions, >>> we’re happy to get responses here. >>> >>> Please note that some of these features have already been implemented (the >>> new error types, some of the optionality changes, collection conformances, >>> etc.), but we are receptive to comments on all of it. The existing >>> proposals will also be updated to incorporate these updates. >>> >>> Thanks for all of your feedback! >>> >>> — Itai >>> >>> <swift-archival-serialization-updates.html> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >>> On Jun 24, 2017, at 1:29 AM, David Hart <da...@hartbit.com >>> <mailto:da...@hartbit.com>> wrote: >>> >>> Sending out again to the whole mailing list ;-) >>> >>> There are a lot of great changes here which make sense after the fact. I'll >>> try to play around with them. >>> >>> One thing I'm concerned about: with the new Optional conformance, why do we >>> still need decodeIfPresent and encodeIfPresent? They seem superfluous now, >>> and potentially confusing. Should users call >>> encodeIfPresent/decodeIfPresent or encode/decode with an optional type? Do >>> the have the same semantics? >>> >>> On 23 Jun 2017, at 21:47, Itai Ferber via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> >>>> Hi swift-evolution, >>>> >>>> Over the course of the past few weeks, we’ve been gathering feedback about >>>> the outcome of SE-0166 >>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md> >>>> and SE-0167 >>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0167-swift-encoders.md> >>>> (both internally and externally), and we gathered a collection of updates >>>> that we’re going to introduce to the proposals and to the implementation. >>>> >>>> Attached is rendered HTML (I don’t want to make your mail clients unusable >>>> like last time!) that lays out what we’d like to do. We’re not looking to >>>> do a full review of these changes, but if you have feedback or questions, >>>> we’re happy to get responses here. >>>> >>>> Please note that some of these features have already been implemented (the >>>> new error types, some of the optionality changes, collection conformances, >>>> etc.), but we are receptive to comments on all of it. The existing >>>> proposals will also be updated to incorporate these updates. >>>> >>>> Thanks for all of your feedback! >>>> >>>> — Itai >>>> >>>> <swift-archival-serialization-updates.html> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution