Codable with references?

The reason for that is due to the fact that keyed containers are generic on the key type the user requests of them — e.g. KeyedDecodingContainer<MyType.CodingKeys>. The issue is that MyType.CodingKeys doesn’t have to have a .super key, which means that MyType.CodingKeys(stringValue: “super”, intValue: nil) returns nil in most cases.

A default implementation would have to pass something in to call into superEncoder(forKey:), but there’s very often no key to pass in.

The fact that keyed containers are generic on a key type is mostly a benefit for the API consumer, though — under the hood, the encoder/decoder can do whatever it wants. JSONEncoder creates a new _JSONReferencingEncoder with the _JSONKey.super key, and can do so because the _JSONReferencingEncoder initializer is not generic on a specific key type — it’ll accept any old CodingKey.

Note that on decode, things work a little bit differently. JSONDecoder has to work around this using a private _superDecoder(forKey:) which is similarly not generic, and the other generic methods call into it.

1 Like