Created
October 3, 2017 00:54
-
-
Save magicien/4ff6d19968ac07f1eaa4d588ecf8b5c9 to your computer and use it in GitHub Desktop.
How should I inherit Codable class?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
let json = """ | |
{ | |
"a": 1, | |
"b": 2, | |
"c": 3 | |
} | |
""".data(using: .utf8)! | |
let decoder = JSONDecoder() | |
class A: Codable { | |
let a: Int | |
} | |
let a = try! decoder.decode(A.self, from: json) | |
dump(a) // a: 1 | |
class B: A { | |
// let b: Int // 初期値が無いとコンパイルエラーになる | |
var b: Int = 0 | |
// CodingKeys を指定しても結果は同じ(bが無視される) | |
} | |
let b = try! decoder.decode(B.self, from: json) | |
dump(b) // a: 1, b: 0 | |
class C: A { | |
var c: Int = 0 | |
// super.init を呼べばaはパースされるが、cは無視される。 | |
required init(from decoder: Decoder) throws { | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
try super.encode(to: encoder) | |
} | |
} | |
let c = try! decoder.decode(C.self, from: json) | |
dump(c) // a: 1, c: 0 | |
class B2: A { | |
let b: Int | |
enum CodingKeys: String, CodingKey { | |
case b | |
} | |
// 自分で真面目にパースすれば大丈夫。 | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.b = try container.decode(Int.self, forKey: .b) | |
try super.init(from: decoder) | |
} | |
} | |
let b2 = try! decoder.decode(B2.self, from: json) | |
dump(b2) // a: 1, b: 2 | |
class C2: B { | |
let c: Int | |
enum CodingKeys: String, CodingKey { | |
case c | |
} | |
// initを書いていないBは素通りするけど、aとcはパースできる。 | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.c = try container.decode(Int.self, forKey: .c) | |
try super.init(from: decoder) | |
} | |
} | |
let c2 = try! decoder.decode(C2.self, from: json) | |
dump(c2) // a: 1, b: 0, c: 3 | |
class C3: B2 { | |
let c: Int | |
// CodingKeys はB2で使っているので同じ名前を使うと怒られる | |
//enum CodingKeys: String, CodingKey { | |
enum MyCodingKeys: String, CodingKey { | |
case c | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: MyCodingKeys.self) | |
self.c = try container.decode(Int.self, forKey: .c) | |
try super.init(from: decoder) | |
} | |
} | |
let c3 = try! decoder.decode(C3.self, from: json) | |
dump(c3) // a: 1, b: 2, c: 3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment