Swift 可以实现Void和Codable的泛型
这里我有一个用于api结果的结构Swift 可以实现Void和Codable的泛型,swift,Swift,这里我有一个用于api结果的结构 struct Response<Result> { let status: Int let message: String let result: Result } 我遇到的问题是,一些响应没有result键,我希望能够像Void类型一样使用Response对象,而不是Response 目前我有一种可能的解决方法,只需声明另一个响应类型,其中没有结果变量,如下所示: struct BaseResponse { let
struct Response<Result> {
let status: Int
let message: String
let result: Result
}
我遇到的问题是,一些响应没有result
键,我希望能够像Void
类型一样使用Response
对象,而不是Response
目前我有一种可能的解决方法,只需声明另一个响应
类型,其中没有结果
变量,如下所示:
struct BaseResponse {
let status: Int
let message: String
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(Int.self, forKey: .status)
message = try container.decode(String.self, forKey: .message)
if Result.self is Nothing.Type {
result = Nothing() as! Result
} else {
result = try container.decode(Result.self, forKey: .result)
}
}
有没有办法避免我声明另一个Response
类型
我试着做了以下几件事,但都不管用
Void
符合Codable
结果:Void
从不
也将不起作用,因为它没有自己的初始值设定项,因此我无法将其与可编码
Codable
的Nothing
类型,如下所示let response: Response<Nothing> = Response(
status: 200,
message: "Success",
result: .nothing
)
or
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.status = try container.decode(forKey: .status)
self.message = try container.decode(forKey: .message)
// These lines don't work.
if let result = try container.decodeIfPresent(Result.self, forKey: .result) {
self.result = result
} else {
self = .nothing
}
}
let response:response=response(
现状:200,
信息:“成功”,
结果:。没有
)
或
public init(来自解码器:解码器)抛出{
let container=try decoder.container(keyedBy:CodingKeys.self)
self.status=try container.decode(forKey:.status)
self.message=try container.decode(forKey:.message)
//这些线不行。
如果let result=try container.decodeIfPresent(result.self,forKey:.result){
self.result=结果
}否则{
self=。什么都没有
}
}
但问题是我不能为
Nothing
类型指定decodeIfPresent
方法。到此为止。将结果制作成可选的类型结果?
。现在,当响应包含针对result
键的值时,它将在result
属性中设置。否则,如果不存在结果
键,它将保持为nil
struct Response<Result: Codable>: Codable {
let status: Int
let message: String
let result: Result? //here....
}
struct响应:可编码{
let状态:Int
让消息:字符串
让结果:结果?//这里。。。。
}
解析如下数据:
do {
let response = try JSONDecoder().decode(Response<String>.self, from: data)
print(response)
} catch {
print(error)
}
do{
让response=try JSONDecoder().decode(response.self,from:data)
打印(答复)
}抓住{
打印(错误)
}
根据您的要求,在响应中使用您想要的任何类型
示例:
如果JSON是{“状态”:1,“消息”:“这是一条消息”,“结果”:“QWERTY”}
然后response
是,response(状态:1,消息:“这是一条消息”,结果:可选(“QWERTY”)
如果JSON是{“status”:1,“message”:“这是一条消息”}
然后response
是,response(状态:1,消息:“这是一条消息”,结果:nil))
您可以像这样定义init(from:)
方法:
struct BaseResponse {
let status: Int
let message: String
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(Int.self, forKey: .status)
message = try container.decode(String.self, forKey: .message)
if Result.self is Nothing.Type {
result = Nothing() as! Result
} else {
result = try container.decode(Result.self, forKey: .result)
}
}
您检测到您处于响应
情况,并完全跳过对结果的解码。这样,在需要结果的情况下,您可以保持正常的结果
解码,并且可以将其保留为非可选的。只需在响应
中去掉泛型,并将结果
设置为可选,但这将无法将结果
作为泛型参数,我还不如把它做成result:Any?
,这样似乎就可以了。你确定你需要使用泛型吗?是的,这样我就不用做空检查了。是的,我明白了,这是我最初的实现,但是这样做意味着我必须对结果
执行空检查,这是我不想做的,这就是为什么我创建了另一个ResponseType,其中没有结果
。但是在中,也不需要检查结果类型。在任何情况下,当使用结果时,您需要检查结果中是否有任何值。我认为这会导致崩溃,但它起到了作用。我尝试使用扩展扩展响应来实现这一点,结果是:什么都没有
和扩展响应
,但它不起作用。
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(Int.self, forKey: .status)
message = try container.decode(String.self, forKey: .message)
if Result.self is Nothing.Type {
result = Nothing() as! Result
} else {
result = try container.decode(Result.self, forKey: .result)
}
}