swift 无法将类型“Model”的返回表达式转换为返回类型“Model”

ohfgkhjo  于 2023-11-16  发布在  Swift
关注(0)|答案(2)|浏览(132)

我在使用泛型函数实现泛型类时遇到错误。下面是错误详细信息:

Cannot convert return expression of type 'Model' to return type 'Model'

字符串

下面是我的泛型类:

public class URLCacheAdapter<Model>:LoaderProtocol{

    public let adaptee:URLCache
    public let mapper: (Data,URLResponse) throws -> Model
    
    public typealias Mapper = (Data,URLResponse) throws -> Model
    
    public init(adaptee: URLCache,
                mapper: @escaping (Data,URLResponse) throws -> Model) {
        self.adaptee = adaptee
        self.mapper = mapper
    }
    
    public enum CacheErrors:Swift.Error{
        case dataNotFound
    }
    
    public func load<Model>() async throws -> Model {
        guard let cachedResponse = adaptee.cachedResponse(for: requet) else{
            throw CacheErrors.dataNotFound
        }
        return mapper(cachedResponse.data,cachedResponse.response) // Error here
    }
}

协议:

public protocol LoaderProtocol{
    func load<T>() async throws -> T
}

通用Map器:

public class DataMapper{

    public enum Errors: Error{
        case invalidData
    }

    public static func map(_ data:Data,from response:HTTPURLResponse) throws -> People{
        guard response.statusCode == 200, let root = try? JSONDecoder().decode(PeopleModel.self, from: data) else{
            throw Errors.invalidData
        }
        return ConvertModelToDto.convertToPeopleData(model: root)
    }
}


有人能帮助理解这个问题吗?

r7knjye2

r7knjye21#

在类URLCacheAdapter中,有一个泛型类型Model

class URLCacheAdapter<Model>:LoaderProtocol

字符串
在函数load中,您也有一个泛型类型Model

func load<Model>()


它们具有相同的名称,但不是相同的类型。

2w2cym1i

2w2cym1i2#

public class URLCacheAdapter<Model>:LoaderProtocol{

字符串
这将创建一个名为Model的类型参数,专门用于URLCacheAdapter。

public func load<Model>() async throws -> Model {


这创建了一个完全无关的类型参数Model,它专门指定load(),并且是load()承诺返回的类型。它由调用者选择,我强调,它与URLCacheAdapter.Model完全无关。

public protocol LoaderProtocol{
    func load<T>() async throws -> T
}


这个协议说,所有符合的类型都实现了一个方法load(),该方法将返回由调用者选择的类型,不管是什么类型,或者抛出。这通常不是你的意思。你可能的意思是:

public protocol LoaderProtocol{
    associatedtype T
    func load() async throws -> T
}


此协议要求load()返回由实现选择的类型。也就是说,尝试创建这样的协议通常表明是very common design mistake。这里的一般错误是,您可能根本不需要URLCacheAdapter。您希望使Model类型符合某些可获取类型。(或可缓存,或类似)协议。正确的设计取决于你在这里要做什么。但请参阅上面的链接。它涵盖了这个问题的一种特别常见的形式。

相关问题