Json 使用Swift 4’解码Void;s可解码
我有一个通用的REST请求: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
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