Json 使用Swift 4’解码Void;s可解码

Json 使用Swift 4’解码Void;s可解码,json,swift,decodable,Json,Swift,Decodable,我有一个通用的REST请求: struct Request<T> {…} 现在我想表示,泛型类型必须符合Decodable,以便我可以解码来自服务器的JSON响应: struct Request<T> where T: Decodable {…} struct Animal: Decodable {…} 我通过将Decodable一致性添加到Void来解决这个问题的恶意尝试很快被编译器发现: extension Void: Decodable {…} // Error

我有一个通用的REST请求:

struct Request<T> {…}
现在我想表示,泛型类型必须符合
Decodable
,以便我可以解码来自服务器的JSON响应:

struct Request<T> where T: Decodable {…}
struct Animal: Decodable {…}
我通过将
Decodable
一致性添加到
Void
来解决这个问题的恶意尝试很快被编译器发现:

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

将请求置于返回类型之上感觉是正确的。有没有一种方法可以让它与
Void
返回类型一起工作?(例如,只在服务器上创建内容而不返回任何内容的请求。)

一个简单的解决方法是引入一个自定义的“无回复”类型,该类型将替换
Void

struct NoReply: Decodable {}

不可能将
Void
符合
可解码
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
所以我的建议是增加“诺雷普利的独特性(佐尔的答案)):


也许我误解了这个问题,但这取决于你——开发人员——如何避免
Void
requests我可以理解你的观点,但与此同时,如果某事物是x上的泛型,那么
Void
又称为零元组
()
应该是x的有效值。毕竟它是平凡的
相等的
可解码的
@zoul仍然想知道
请求
应该是什么意思。为什么要使用这样的东西?如果这是一种响应类型,它永远不会是
无效的
。它可以是空的,但永远不会是
无效的
。dif是什么空函数和空函数之间的引用对我来说,在普通函数中有一个完美的类比,返回
Void
的请求与返回
Void
的函数是一样的。两者都只用于副作用。这个解决方案非常棒。谢谢!这对我不起作用,我得到了一个解码错误。数据被上下文破坏:
Context(codingPath:[],debugDescription:“给定的数据不是有效的JSON.”,underlineError:Optional(Error Domain=NSCocoaErrorDomain Code=3840“No value.”UserInfo={NSDebugDescription=No value.}))
@Marmoy可能您正在尝试解码一个空数据。JSONDecoder要求输入数据是有效的JSON文档。作为一种解决方法,您可以检测响应数据是否为空,并在这种情况下将其替换为模拟的空JSON数据:
let emptyJson=“{}”。数据(使用:.utf8)
struct NoReply: Decodable {}
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
struct VoidResult: Codable {
    var id = UUID()
}

let voidInstanceDecodedFromError = try! JSONDecoder().decode(VoidResult.self, from: data2)
//DecodingError.typeMismatch - Now its fine - as expected