【发布时间】:2019-07-03 23:43:22
【问题描述】:
这里我有一个用于 api 结果的结构
struct Response<Result> {
let status: Int
let message: String
let result: Result
}
现在通常让它符合Codable 意味着Result 对象需要是Codable。这样做看起来像以下之一
struct Response<Result: Codable>: Codable {...}
// or
extension Response: Codable where Result: Codable {}
我遇到的问题是某些响应没有result 键,我希望能够使用Response 对象,就像Void 类型一样,而不是Response<Void>,就像这样@ 987654321@.
目前我有一个可能的解决方法,只需声明另一个 Response 类型,其中没有 result 变量,如下所示:
struct BaseResponse {
let status: Int
let message: String
}
有没有办法让我不必声明另一个 Response 类型?
我已尝试执行以下操作,但没有任何效果
- 我无法将
Void与Codable一致 - 有另一个扩展符合 codable where
Result: Void
extension Response: Codable where Result: Codable {}
extension Response: Codable where Result: Void {}
-
Never也不起作用,因为它没有自己的初始化程序,因此我不能使其符合Codable - 像这样创建一个符合
Codable的Nothing类型
struct Nothing: Codable, Hashable {
init() {}
static var nothing: Nothing { return .init() }
}
所以我可以使用这样的响应
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
}
}
但问题是我不能有一个特定于Nothing 类型的decodeIfPresent 方法。就这么多。
【问题讨论】:
-
去掉
Response中的泛型,使result成为可选 -
但这会破坏将
result作为通用参数的意义,我不妨将它变成result: Any? -
这似乎可以解决问题。您确定需要使用泛型吗?
-
是的,所以我不必进行空值检查。
标签: swift