简体   繁体   中英

Cannot convert return expression of generic protocol's function type implementation

I'd like to use swift generics in a way described below:

class ResponseContainer {

}

protocol DisplayManageable {

    func getModel<ModelType: ResponseContainer>() -> ModelType?
}

class DisplayBaseManager<ObtainedModelType: ResponseContainer>: NSObject, DisplayManageable {

    var modelObtained: ObtainedModelType? = nil

    func getModel<ObtainedModelType>() -> ObtainedModelType? {

        return modelObtained
    }
}

But I have a problem with this code, more precisely there is a problem in this line:

return modelObtained

And I'm getting the error:

Cannot convert return expression of type 'ObtainedModelType?' to return type 'ObtainedModelType?'

And now my simple question, why can't I do that? What's wrong with that?

Generics in protocol's function and in class definitions are the same. Everything looks fine in my opinion and logically is ok, so why cannot I do so?

In

func getModel<ObtainedModelType>() -> ObtainedModelType? { ... }

ObtainedModelType introduces a local generic placeholder, and that hides the ObtainedModelType from the class definition

class DisplayBaseManager<ObtainedModelType: ResponseContainer>

This causes the strange looking error message

Cannot convert return expression of type 'ObtainedModelType?' to return type 'ObtainedModelType?'

because return modelObtained has the generic type ObtainedModelType? from the class definition, but the expected return type is ObtainedModelType? from the method definition.

What you probably want is a protocol with an associated type

protocol DisplayManageable {
    associatedtype ModelType: ResponseContainer
    func getModel() -> ModelType?
}

and a class adopting this protocol with ModelType == ObtainedModelType :

class DisplayBaseManager<ObtainedModelType: ResponseContainer>: NSObject, DisplayManageable {

    var modelObtained: ObtainedModelType? = nil
    func getModel() -> ObtainedModelType? {
        return modelObtained
    }
}

Łukasz, I don't now why it doesn't compile but I found the way to compile it. Just change the return statement:

return modelObtained as? ObtainedModelType

But I'm still waiting for someone to explain the reason for error in the original code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM