首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift 4:与泛型的角色转换问题

Swift 4:与泛型的角色转换问题
EN

Stack Overflow用户
提问于 2018-01-31 16:12:48
回答 2查看 1K关注 0票数 0

我是Swift的新手,当了很多年的目标C开发人员。我很难理解类型铸造是如何与仿制药一起工作的。

我有两个功能,就是用Alamofire +可编码和Alamofire + ObjectMapper进行对象映射。就像这样:

代码语言:javascript
复制
public func performRestOperationWithDecodable<ResponseClass: Decodable>(
    _ restOperationType: NetworkServiceRestOperationType,
    pathUrl: URLConvertible,
    parameters: Parameters,
    encoding: ParameterEncoding,
    savedAuthType: NetworkServiceAuthType,
    activityIndicator: ActivityIndicatorProtocol?,
    successBlock: @escaping (_ responseObject: DataResponse<ResponseClass>) -> Void,
    errorBlock:@escaping (_ error: Error, _ validResponse: Bool) -> Void) {

    let restConfiguration = self.setupRestOperation(
        savedAuthType: savedAuthType,
        pathUrl: pathUrl,
        activityIndicator: activityIndicator)

    Alamofire
        .request(
            restConfiguration.url,
            method: .get,
            parameters: parameters,
            encoding: encoding,
            headers: restConfiguration.headers)
        .validate(
            contentType: Constants.Network.DefaultValidContentTypeArray)
        .responseDecodableObject(
            queue: self.dispatchQueue,
            keyPath: nil,
            decoder: JSONDecoder(),
            completionHandler: { (responseObject: DataResponse<ResponseClass>) in
                self.completionRestOperation(
                    responseObject: responseObject,
                    activityIndicator: activityIndicator,
                    successBlock: successBlock,
                    errorBlock: errorBlock)
            })
}
代码语言:javascript
复制
public func performRestOperationWithObjectMapper<ResponseClass: BaseMappable>(
    _ restOperationType: NetworkServiceRestOperationType,
    pathUrl: URLConvertible,
    parameters: Parameters,
    encoding: ParameterEncoding,
    savedAuthType: NetworkServiceAuthType,
    activityIndicator: ActivityIndicatorProtocol?,
    successBlock: @escaping (_ responseObject: DataResponse<ResponseClass>) -> Void,
    errorBlock: @escaping (_ error: Error, _ validResponse: Bool) -> Void) {

    let restConfiguration = self.setupRestOperation(
        savedAuthType: savedAuthType,
        pathUrl: pathUrl,
        activityIndicator: activityIndicator)

    Alamofire
        .request(
            restConfiguration.url,
            method: .get,
            parameters: parameters,
            encoding: encoding,
            headers: restConfiguration.headers)
        .validate(
            contentType: Constants.Network.DefaultValidContentTypeArray)
        .responseObject(
            queue: self.dispatchQueue,
            keyPath: nil,
            mapToObject: nil,
            context: nil,
            completionHandler: { (responseObject: DataResponse<ResponseClass>) in
                self.completionRestOperation(
                    responseObject: responseObject,
                    activityIndicator: activityIndicator,
                    successBlock: successBlock,
                    errorBlock: errorBlock)
            })
}

每个函数都有一个符合所使用映射器所需的适当协议的泛型类型(可解码用于可编码,可映射用于ObjectMapper)。这些有趣的事情就像预期的一样。现在,我正在尝试编写第三个函数,它具有第三个泛型类型,但不符合任何协议,并根据配置参数强制转换到适当的泛型。就像这样:

代码语言:javascript
复制
public func performRestOperation<ResponseMappedClass :AnyObject>(
    _ restOperationType: NetworkServiceRestOperationType,
    pathUrl: URLConvertible,
    parameters: Parameters = [:],
    encoding: ParameterEncoding = URLEncoding.queryString,
    savedAuthType: NetworkServiceAuthType,
    activityIndicator: ActivityIndicatorProtocol?,
    successBlock: @escaping (_ responseObject: ResponseMappedClass) -> Void,
    errorBlock: @escaping (_ error: Error, _ validResponse: Bool) -> Void) {

    if self.canDoRestOperation(errorBlock: errorBlock) != true {
        return
    }

    switch self.mappingType {
        case .Codable:
            self.performRestOperationWithDecodable(
                restOperationType,
                pathUrl: pathUrl,
                parameters: parameters,
                encoding: encoding,
                savedAuthType: savedAuthType,
                activityIndicator: activityIndicator,
                successBlock: { (responseObject: DataResponse<ResponseMappedClass>) in
                    let response: ResponseMappedClass = responseObject.result.value!
                    successBlock(response)
                } as! (DataResponse<ResponseMappedClass & Decodable>) -> Void,
                errorBlock: { (error: Error, validResponse: Bool) in
                    errorBlock(error, validResponse)
                })

        case .ObjectMapper:
            // TODO

            break
    }
}

使用说明:as! (DataResponse<ResponseMappedClass & Decodable>) -> Void,我尝试将“泛型”类类型ResponseMappedClass转换为同一个类,但使用Codable支持。但这条指令并没有编译:

非协议、非类类型“ResponseMappedClass”不能在协议约束类型中使用。

在所有这些过程之后,各种泛型将表示相同的类,例如SomeModelObject,将来实现CodableMappable或其他东西,所以编译时通常的类型替换仍然必须工作。

有什么建议吗?在斯威夫特完全不可能做到吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-31 18:09:38

我认为不可能将泛型类型与协议结合使用。编译器不将它们视为类或协议类型。还有一点是代码有问题,您正在使用self.mappingType来判断它是Decodable类型还是Mapable类型。如果是self.mappingType == .Codable,但ResponseMappedClass没有确认Decodable协议呢?我能告诉你的是功能超载。创建3个功能:

代码语言:javascript
复制
    public func performRestOperation<ResponseMappedClass: AnyObject>(...) where ResponseMappedClass: Decodable {

    }

    public func performRestOperation<ResponseMappedClass: AnyObject>(...) where ResponseMappedClass: BaseMappable {

    }

    public func performRestOperation<ResponseMappedClass: AnyObject>(...) {   

    }

在最后一个只是抛出一个错误。根据泛型参数类型,将调用正确的funcion。

票数 0
EN

Stack Overflow用户

发布于 2018-02-08 12:15:25

代码语言:javascript
复制
(DataResponse<ResponseMappedClass & Decodable>) 

我认为您做错的是ResponseMappedClass是一个,而Decodable是一个协议。而且不能将类和协议类型组合在一起。

所以,这个错误和它说的完全一样。

非协议、非类类型“ResponseMappedClass”不能在协议约束类型中使用。

像这样的东西会工作,因为这两种类型都是协议。

代码语言:javascript
复制
as! (DataResponse<Codable & Decodable>) -> Void
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48546636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档