swift - 具有通用成功类型的结果类型
问题描述
我正在将项目从自定义 Result 类型切换到本机 Swift Result 类型,并不断遇到此错误消息或类似错误消息:
Member 'success' in 'Result<_, Error>' produces result of type 'Result<Success, Failure>', but context expects 'Result<_, Error>'
protocol DataFetcher {
func request<T>(completion: @escaping (Result<T, Error>) -> Void )
}
struct RandomFetcher: DataFetcher {
func request<String>(completion: @escaping (Result<String, Error>) -> Void) {
let str = "Hello"
completion(.success(str))
}
}
这个想法是为不同的数据提取调用制作一堆通用的 Fetcher,并将它们传递给拥有var fetcher: DataFetcher
属性的 VC。VC 知道他们期望从他们的请求中得到哪些具体类型。我不能使用 an associated type
,因为我需要将一堆这些保存在一个数组中,我认为我可以只使用泛型实现 - 但似乎 Result 类型在协议中被声明为泛型,意味着当我在实现中指定它时它不会接受。我错过了什么?
解决方案
func request<String>(completion: @escaping (Result<String, Error>) -> Void) {
这是 Swift 中一个经典的泛型错误。这并不意味着“请求需要T==String
”。String
这意味着“此函数接受的任意类型称为”。这String
和之间没有关系Swift.String
。
您在这里尝试做的事情违反了协议。协议说调用者可以选择他们想要的任何 T。您不能使用受限制的 T 来遵守该协议。
如果您希望符合类型 (RandomFetcher) 来决定 T 的类型,那么您必须使用关联类型(这就是关联类型的含义)。
您尝试构建的东西很常见,但并非微不足道,并且需要以不同的方式思考问题。我将在本系列中逐步介绍。
推荐阅读
- python - 看不懂这行 Python 代码
- flutter - 当项目具有动态高度时,如何根据设备方向创建动态颤动网格布局
- c++ - 不推荐复制交换习语?
- jquery - jQuery - 输入 changeclass 和 value 到 fontawesome
- java - 无法使用 R 从 Java 中的 Salesforce 获取数据。
- replace - DATASTAGE 替换 csv 文件中的值
- android - 捆绑失败:错误:插件 0 提供了“默认”的无效属性
- javascript - 是 setInterval 减慢我的网站
- android - Android Studio 3.1.3 android:roundIcon
- powershell - (Azure)如何更改 Recoveryservices 保管库中每个策略的保留期