swift - 从其嵌套类型推断泛型类型
问题描述
我正在尝试创建一个Fetchable
协议,该协议包含从中获取对象的位置作为其类型的一部分,而不是fetch
使用显式类型参数编写函数,如下所示:
func fetch<Model: Fetchable>(_ type: Model.Type, path: Model.Path) -> AnyPublisher<[Model], Error> {
print(path.value)
// ...
}
我想Model
从Model.Path
参数中推断:
func fetch<Model: Fetchable>(path: Model.Path) -> AnyPublisher<[Model], Error> {
print(path.value)
// ...
}
这是由@RobNapier 的方法启发而来的。它并不完全相同,因此我可能会遗漏重要的细节以使其发挥作用。
这是我所拥有的:
protocol Locatable {
associatedtype Model
var value: String { get }
}
protocol Fetchable: Codable {
associatedtype Path: Locatable where Path.Model == Self
}
struct Message {
let content: String
}
extension Message: Fetchable, Codable {
enum Path: Locatable {
typealias Model = Message
case forUser(_ userId: String)
var value: String {
switch self {
case .forUser(let userId): return "/user/\(userId)/messages"
}
}
}
}
当我打电话时fetch
,我得到一个错误"Generic parameter 'Model' could not be inferred"
let pub = fetch(path: Message.Path.forUser("123"))
但这适用于fetch
明确接受类型参数的 a (甚至推断其自己的 Message.Path 类型):
let pub = fetch(Message.self, .forUser("123"))
知道如何(如果可能的话)解决这个问题吗?
解决方案
信息不足以推断,但如果我们写
let pub: AnyPublisher<[Message], Error> = fetch(path: Message.Path.forUser("123"))
一切顺利。
更新:嵌套类型只是一种不可分割的类型,因此为了帮助快速推断父级,我们需要反转声明,如下所示(使用 Xcode 12.1 测试):
func fetch<Path: Locatable>(path: Path) ->
AnyPublisher<[Path.Model], Error> where Path.Model: Fetchable {
现在你想要的表达成为可能
let pub = fetch(path: Message.Path.forUser("123"))
推荐阅读
- sdl-2 - SDL_RenderPresent() 实现
- java - 可变数量的输入 - Java
- javascript - 反正有没有简化这个Javascript代码
- python - 将字典分配给类对象
- sqlite - 进行左连接时,我如何从右表中获取值
- c++ - 是否明确定义了哪个线程调用 thread_local 存储的构造函数?
- pycharm - 这种运行本地虚拟机以严格充当远程 shell/python 解释器的方法是一个明智的想法吗?
- ansible - Ansible 处理程序和条件
- azure-devops - 如何在冲刺任务板中将时间跟踪单位从小时“h”更改为天“d”?
- vba - 使用 cmd.exe 调用 shell 与 Wscript.Shell