Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't call generic function from a generic struct

Tags:

generics

swift

I have a problem when trying to create a function in extension which would call another generic function. I created very simple example to display the problem :

protocol Target {}
enum api {
    case user
}
extension api: Target {}
protocol Mappable {}

struct User {}
extension User: Mappable {}

struct Provider<A: Target> {

}
extension Provider {

    func requestObject<T: Mappable>(_ token: A, type: T.Type){
        //some code
    }

    func getUser() {

        requestObject(api.user, type: User.self)
        //This code creates Error:  Cannot invoke 'requestObject' with an argument list of type '(api, type: User.Type)'
    }

}

Can anyone help and explain how can create a function getUser() and call requestObject. I know that one solution would be to make struct Provider non-generic, but than It will limit Provider, therefore its not really a solution.

Thanks for help

like image 252
Vanilla Thunder Avatar asked Dec 04 '25 13:12

Vanilla Thunder


1 Answers

The issue is that by extending the generic Provider type without any type constraints and declaring the getUser function as you did, the compiler can only infer the type of A to be Api, which is more restrictive than A:Target. You need to use conditional conformance to let the compiler know that the specific getUser implementation should only exist for Provider types specialised with the api type.

extension Provider where A == Api {
    func getUser() {
        requestObject(Api.user, type: User.self)
    }
}

You should also conform to the Swift naming convention, which is upperCamelCase for types, so change api to Api.

like image 85
Dávid Pásztor Avatar answered Dec 07 '25 13:12

Dávid Pásztor