我有一个通用的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'我试图通过向Void添加Decodable一致性来解决这个问题,但很快就被编译器发现了:
extension Void: Decodable {…} // Error: Non-nominal type 'Void' cannot be extended让请求泛型而不是返回类型是正确的。有没有办法让它与Void返回类型一起工作?(例如,只在服务器上创建内容而不返回任何内容的请求。)
发布于 2017-08-11 22:02:16
一种简单的解决方法是引入一个自定义的“无回复”类型来替换Void
struct NoReply: Decodable {}不可能使Void符合Decodable。Void只是一个空元组的类型别名,(),目前元组不能符合协议,但它们最终会符合协议。
发布于 2020-11-19 03:30:44
我发现有时可以将其他类型的编码对象解码为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加上“唯一性”(祖尔的答案):
struct VoidResult: Codable {
var id = UUID()
}
let voidInstanceDecodedFromError = try! JSONDecoder().decode(VoidResult.self, from: data2)
//DecodingError.typeMismatch - Now its fine - as expectedhttps://stackoverflow.com/questions/45635018
复制相似问题