首页 > 解决方案 > 具有通用成功类型的结果类型

问题描述

我正在将项目从自定义 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 类型在协议中被声明为泛型,意味着当我在实现中指定它时它不会接受。我错过了什么?

标签: swift

解决方案


func request<String>(completion: @escaping (Result<String, Error>) -> Void) {

这是 Swift 中一个经典的泛型错误。这并不意味着“请求需要T==String”。String这意味着“此函数接受的任意类型称为”。这String和之间没有关系Swift.String

您在这里尝试做的事情违反了协议。协议说调用者可以选择他们想要的任何 T。您不能使用受限制的 T 来遵守该协议。

如果您希望符合类型 (RandomFetcher) 来决定 T 的类型,那么您必须使用关联类型(这就是关联类型的含义)。

您尝试构建的东西很常见,但并非微不足道,并且需要以不同的方式思考问题。我将在本系列中逐步介绍。


推荐阅读