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 <[email protected]> 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 <[email protected]
>> <mailto:[email protected]>> 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
>> <[email protected] <mailto:[email protected]>> 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
>>> [email protected] <mailto:[email protected]>
>>> 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 <[email protected]
>>> <mailto:[email protected]>> 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
>>> <[email protected] <mailto:[email protected]>> 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
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution