Reputation: 543
The following code doesn't compile:
import Foundation
import PlaygroundSupport
protocol C : Decodable {
}
class A : C {
let code: Int
}
class B : C {
let blob: Int
}
var c : C.Type
let a = A.self
let b = B.self
let i = 100
if i == 100 {
c = a
}
else if i < 100 {
c = b
}
do {
let data = String("{\"code\": 123}").data(using: .utf8)!
let j = try JSONDecoder().decode(c, from: data)
print(j)
}
catch let error as NSError{
print(error.debugDescription)
}
The error is:
cannot invoke 'decode' with an argument list of type '(C.Type, from: Data)'
let j = try JSONDecoder().decode(c, from: data)
What would be the proper way to declare the c
variable so it could receive or type A
or type B
and still complies with JSONDecoder().decode(...)
signature?
Upvotes: 1
Views: 95
Reputation: 299605
(Bah; never mind my old answer. Hamish is right.)
Add an extension:
extension C {
static func decode(data: Data) throws -> C {
return try JSONDecoder().decode(Self.self, from: data)
}
}
Decode with it:
let j = try c.decode(data: data)
EDIT: I'm not certain what you mean by it not compiling against your code. Perhaps because you have another bug (you don't initialize c
in all legs). Here is what I'm describing, based on your code:
import Foundation
import PlaygroundSupport
protocol C : Decodable {
}
// Adding extension
extension C {
static func decode(data: Data) throws -> C {
return try JSONDecoder().decode(Self.self, from: data)
}
}
class A : C {
let code: Int
}
class B : C {
let blob: Int
}
var c : C.Type = A.self // You have to initialize this for all legs
let a = A.self
let b = B.self
let i = 100
if i == 100 {
c = a
}
else if i < 100 {
c = b
}
do {
let data = String("{\"code\": 123}").data(using: .utf8)!
// Rewrite this line
let j = try c.decode(data: data)
print(j)
}
catch let error as NSError{
print(error.debugDescription)
}
Upvotes: 1