使用 Swift 4 的 Decodable 解码 Void



>我有一个通用的 REST 请求:

struct Request<T> {…}

T是请求的返回类型,例如:

struct Animal {…}
let animalRequest = Request<Animal>
let animal: Animal = sendRequest(animalRequest)

现在我想表达泛型类型必须符合Decodable,以便我可以解码来自服务器的 JSON 响应:

struct Request<T> where T: Decodable {…}
struct Animal: Decodable {…}

这是有道理的并且有效——直到我到达一个没有响应的请求,一个Request<Void>.编译器对此不满意:

Type 'Void' does not conform to protocol 'Decodable'

我试图通过将Decodable一致性添加到Void来解决这个问题的恶作剧尝试很快被编译器发现:

extension Void: Decodable {…} // Error: Non-nominal type 'Void' cannot be extended

将请求泛型放在返回类型上感觉是正确的。有没有办法让它与Void返回类型一起使用?(例如,只在服务器上创建某些内容而不返回任何内容的请求。

一个简单的解决方法是引入一个自定义的"no-reply"类型来替换Void

struct NoReply: Decodable {}

不符合DecodableVoid是不可能的。Void只是空元组的类型别名,(),元组目前无法符合协议,但它们最终会。

我发现有时其他类型的其他编码对象可以解码为 NoReply.self。例如,自定义错误类型(枚举(可以是。

本案的游乐场示例:

enum MyError: String, Codable {
case general
}
let voidInstance = VoidResult()
let errorInstance = MyError.general
let data1 = try! JSONEncoder().encode(voidInstance)
let data2 = try! JSONEncoder().encode(errorInstance)
let voidInstanceDecoded = try! JSONDecoder().decode(VoidResult.self, from: data1)
//VoidResult as expected
let errorInstanceDecoded = try! JSONDecoder().decode(MyError.self, from: data2)
//MyError.general as expected
let voidInstanceDecodedFromError = try! JSONDecoder().decode(VoidResult.self, from: data2)
//VoidResult - NOT EXPECTED
let errorInstanceDecodedFromVoid = try! JSONDecoder().decode(ScreenError.self, from: data1)
//DecodingError.typeMismatch - Expected

所以我的建议是添加"NoReply 的唯一性(zoul 的答案((:

struct VoidResult: Codable {
var id = UUID()
}
let voidInstanceDecodedFromError = try! JSONDecoder().decode(VoidResult.self, from: data2)
//DecodingError.typeMismatch - Now its fine - as expected

相关内容

  • 没有找到相关文章

最新更新