Swift:将类型从属性传递给泛型函数

编程入门 行业动态 更新时间:2024-10-20 06:17:36
本文介绍了Swift:将类型从属性传递给泛型函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

对于我的网络模块,我具有用于访问API不同部分的以下协议:

For my networking module, I have this protocol that I adopt for accessing different parts of the API:

protocol Router: URLRequestConvertible { var baseUrl: URL { get } var route: Route { get } var method: HTTPMethod { get } var headers: [String: String]? { get } var encoding: ParameterEncoding? { get } var responseResultType: Decodable.Type? { get } }

我正在采用带有如下枚举的枚举:

I'm adopting this with enums that look like this:

enum TestRouter: Router { case getTestData(byId: Int) case updateTestData(byId: Int) var route: Route { switch self { case .getTestData(let id): return Route(path: "/testData/\(id)") case .updateTestData(let id): return Route(path: "/testDataOtherPath/\(id)") } } var method: HTTPMethod { switch self { case .getTestData: return .get case .updateTestData: return .put } } var headers: [String : String]? { return [:] } var encoding: ParameterEncoding? { return URLEncoding.default } var responseResultType: Decodable.Type? { switch self { case .getTestData: return TestData.self case .updateTestData: return ValidationResponse.self } } }

我想使用 Codable 来解码嵌套的Api响应.每个响应都包含一个令牌和一个结果,其内容取决于请求路由.

I want to use Codable for decoding nested Api responses. Every response consists of a token and a result which content is depending on the request route.

对于发出请求,我想使用上面 enum 的 responseResultType 属性中指定的类型.

For making the request I want to use the type specified in the responseResultType property in the enum above.

struct ApiResponse<Result: Decodable>: Decodable { let token: String let result: Result } extension Router { func asURLRequest() throws -> URLRequest { // Construct URL var completeUrl = baseUrl.appendingPathComponent(route.path, isDirectory: false) completeUrl = URL(string: completeUrl.absoluteString.removingPercentEncoding ?? "")! // Create URL Request... var urlRequest = URLRequest(url: completeUrl) // ... with Method urlRequest.httpMethod = method.rawValue // Add headers headers?.forEach { urlRequest.addValue($0.value, forHTTPHeaderField: $0.key) } // Encode URL Request with the parameters if encoding != nil { return try encoding!.encode(urlRequest, with: route.parameters) } else { return urlRequest } } func requestAndDecode(completion: @escaping (Result?) -> Void) { NetworkAdapter.sessionManager.request(urlRequest).validate().responseData { response in let responseObject = try? JSONDecoder().decode(ApiResponse<self.responseResultType!>, from: response.data!) completion(responseObject.result) } } }

但是在我的 requestAndDecode 方法中,它引发了编译器错误(无法调用类型为'(Any.Type,from:Data)'的参数列表的'decode').我不能这样使用 ApiResponse< self.responseResultType!> .

But in my requestAndDecode method It throws an compiler error (Cannot invoke 'decode' with an argument list of type '(Any.Type, from: Data)'). I can't use ApiResponse<self.responseResultType!> like that.

我可以将此函数设为通用,然后这样调用:

I could make this function generic and call it like this:

TestRouter.getTestData(byId: 123).requestAndDecode(TestData.self, completion:)

但是随后我每次要使用此端点时都必须传递响应类型.

but then I'd have to pass the response type everytime I want to use this endpoint.

我要实现的是扩展功能 requestAndDecode 从自身( responseResultType 属性)获取响应类型信息.

What I want to achieve is that the extension function requestAndDecode takes it response type information from itself, the responseResultType property.

这可能吗?

推荐答案

忽略实际的错误报告,您对 requestAndDecode 有一个基本的问题:这是一个泛型函数,其类型参数在调用时确定声明返回值为 Result 类型的值的站点,但它尝试返回值为 unknown 类型的 self.responseResultType 类型的值

Ignoring the actual error report you have a fundamental problem with requestAndDecode: it is a generic function whose type parameters are determined at the call site which is declared to return a value of type Result yet it attempts to return a value of type self.responseResultType whose value is an unknown type.

如果Swift的类型系统支持此功能,则将需要运行时类型检查,潜在的失败,并且您的代码必须处理该问题.例如.您可以将 TestData 传递给 requestAndDecode ,而 responseResultType 可能是 ValidationResponse ...

If Swift's type system supported this it would require runtime type checking, potential failure, and your code would have to handle that. E.g. you could pass TestData to requestAndDecode while responseResultType might be ValidationResponse...

将JSON调用更改为:

Change the JSON call to:

JSONDecoder().decode(ApiResponse<Result>.self ...

并且类型静态匹配(即使 Result 的实际类型未知).

and the types statically match (even though the actual type that Result is is unknown).

您需要重新考虑您的设计.HTH

You need to rethink your design. HTH

更多推荐

Swift:将类型从属性传递给泛型函数

本文发布于:2023-08-02 11:40:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1277504.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:从属性   函数   类型   Swift

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!