swift - 使用通用参数调用函数需要类型的无参数初始化
问题描述
我无法让使用泛型类型的函数调用使用URLSession
DataTaskPublisher
...
code
我调用的 API 总是以 HTTP 200 响应,并通过带有指示符的字符串在 JSON 中指示它是否成功。
我创建了一个protocol
所有响应对象都符合的,例如:
protocol APIResponse: Decodable {
var code: String { get }
}
我的实际反应是这样的:
struct LoginResponse : APIResponse {
let code: String
let name: String
enum CodingKeys: String, CodingKey {
case code = "code"
case name = "name"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
code = try values.decode(String.self, forKey: .code)
name = try values.decode(String.self, forKey: .name)
}
}
现在我想要一个可以使用的函数:
private func call<T: APIResponse>(_ endpoint: String, using data: Encodable, providing response: T)
-> AnyPublisher<T, Error> {
let request = createRequest(for: endpoint, using: data)
return session
.dataTaskPublisher(for: request)
.map {
$0.data
}
.decode(type: T.self, decoder: decoder)
.tryMap {
response in
if response.code.suffix(1) != "I" {
throw MyError(message: "Error \(code)")
}
return response
}
.eraseToAnyPublisher()
}
到目前为止,一切都很好!
但这是问题......我想这样使用它:
func login() -> AnyPublisher<String, Error> {
call("login", using: LoginRequest(), providing: LoginResponse)
.map {
$0.name
}
.eraseToAnyPublisher()
}
编译器抱怨Type 'LoginResponse.Type' cannot conform to 'APIResponse'; only struct/enum/class types can conform to protocols
我的修复(有效,但很笨拙),它提供了一个无参数init()
并LoginResponse
这样称呼它:call("login", using: LoginRequest(), providing: LoginResponse())
有什么方法可以让 Generic 在没有 no-arg 的情况下工作init()
?
我应该采取完全不同的方法吗?
解决方案
在将参数call
更改为的标题中response
...providing response: T.Type)
并使用.self
call("login", using: "request", providing: LoginResponse.self)
推荐阅读
- javascript - 使用当前脚本路径在脚本中导入 css 文件
- java - RenameTo 似乎随机失败
- csv - Julia 错误地使用科学记数法导入 CSV
- laravel - laravel 背包只显示不禁用元素
- quantum-computing - Q#如何在不破坏量子位状态的情况下读取它?
- ios - CAAnimation - 对“变换”的错误解释?
- swift - 使用 Swift 更改 UITableView 的选定单元格
- c++ - ld: 找不到 -lGL 错误的库
- android - 如何在 recyclerview 适配器和活动中应用 rxjava?
- mysql - 数据库资源管理器没有看到 MySQL J Connect“无法在 MATLAB Java 类路径上找到 JDBC 驱动程序文件”