完成处理程序中的Swift泛型

问题描述

我正在尝试重构dat提取函数,以使其能够用于多种Decodable结构类型。

    func fetchData<T: Decodable>(_ fetchRequest: FetchRequestType,completion: @escaping ((Result<T,Error>) -> Void)) {
    guard !isFetching else { return }
    isFetching = true
    
    guard let url = getURL(fetchRequest) else { assertionFailure("Could not compose URL"); return }
    let urlRequest = URLRequest(url: url)
    
    self.session.dataTask(with: urlRequest) { [uNowned self] (data,response,error) in
        guard let response = response as? HTTPURLResponse,response.statusCode == 200 else {
                self.isFetching = false
                completion(.failure(NSError()))
                return
        }

        guard let data = data else { assertionFailure("No data"); return }
        
        if let jsonData = try? JSONDecoder().decode(T.self,from: data) {
            self.isFetching = false
            completion(.success(jsonData))
        } else {
            assertionFailure("Could not decode JSON data"); return
        }

        
    }.resume()
    
}

但是当我从具有Decodable类型之一的控制器中调用函数时,会出现编译错误

无法推断出通用参数'T'

        networkClient.fetchData(.accountsSearch(searchLogin: text,pageNumber: 1)) { [uNowned self] result in
        switch result {
            case .success(let dataJSON):
                let accountsListJSON = dataJSON as! AccountsListJSON
                let fetchedAccounts = accountsListJSON.items
                    .map({ AccountGeneral(login: $0.login,id: $0.id,avatarURLString: $0.avatarURL,type: $0.type) })
                self.accounts = fetchedAccounts
            
            case .failure(_):
                assertionFailure("Fetching error!")
            
        }
    }

请帮助我找出发生了什么并解决问题。

解决方法

如果该方法没有可以指定静态类型的返回类型,则必须添加一个参数

func fetchData<T: Decodable>(_ fetchRequest: FetchRequestType,type: T.Type,completion: @escaping (Result<T,Error>) -> Void) { ...

并调用它

networkClient.fetchData(.accountsSearch(searchLogin: text,pageNumber: 1),type: AccountsListJSON.self) { [unowned self] result in

并删除低调的as! AccountsListJSON

,

通常,当您调用T函数时,可以通过提供result类型来帮助编译器推断fetchData(_:completion:)类型:

networkClient.fetchData(
    .accountsSearch(searchLogin: text,pageNumber: 1)
) { [unowned self] (result: Result<AccountsListJSON,Error>) in
    ...
}