Add generic function implementation to protocol based on another generic function declaration

Viewed 27

I'd like to create default implementation for convenience protocol function that just calls another protocol function, but can't figure out what's wrong with the code:

protocol RequestManagerProtocol {
    func perform<T: Decodable>(_ request: RequestProtocol) async throws -> (T, Int)
    func perform<T: Decodable>(_ request: RequestProtocol) async throws -> T // Convenience function
}

extension RequestManagerProtocol {
    func perform<T: Decodable>(_ request: RequestProtocol) async throws -> T {
        let (obj, _) = perform<T>(request) // Error: Cannot specialize a non-generic definition
        return obj
    }
}
2 Answers

As the error says, you cannot specialize a function. So you cannot do this perform<T>(request), you have to specify the type returned to your constant:

 let (obj, _): (T, Int) = try await perform(request)

Also, since you're not using the returned Int, you can simply do this:

func perform<T: Decodable>(_ request: RequestProtocol) async throws -> T {
    return try await perform(request).0
}

First of all you have to try await the perform call.

And you have to annotate the (return) type rather than specifying the type in angle brackets

extension RequestManagerProtocol {
    func perform<T: Decodable>(_ request: RequestProtocol) async throws -> T {
        let (obj, _) : (T, Int) = try await perform(request)
        return obj
    }
}
Related