DMCApps
DMCApps

Reputation: 2168

swift - Pass generic type to method with more specific extension requirements

So the title is a little weirdly worded, but here is the basis of what I am looking to do. I want to make a function that can determine if the generic type given extends from a specific protocol and then pass through the type to the more specific method for processing. This would be using the swift programming language to do so.

Psuedo code of what I want to achieve below:

func doStuff<T>(callback: Callback<T>) {
    // Pseudo code of what I want to achieve as I'm not sure the syntax
    // nor if it's even possible
    if T extends Protocol {
        let tExtendsProtocolType = T.Type as Protocol
        mapStuffSpecific<tExtendsProtocolType>(callback: callback)
    } else {
        // Standard Use Case
    }
}

func doStuffSpecific<T: Protocol>(callback: Callback<T> {

}

Thanks in advance

EDIT 1

typealias Callback<T> = (T) -> Void

protocol Protocol {}

struct A {}
struct B: Protocol {}

// I want to be able to use this to do some common set up then call into either doStuff<T> or doStuff<T: Protocol>
func tryDoStuff<T>(callback: Callback<T>) {
    // Do some common setup then call this
    doStuff(callback: callback)
}

func doStuff<T>(callback: Callback<T>) {
    print("doStuff")
}

func doStuff<T: Protocol>(callback: Callback<T>) {
    print("doStuffSpecific")
}

let callbackA: Callback<A> = { _ in } // Just an empty closure
let callbackB: Callback<B> = { _ in }

tryDoStuff(callback: callbackA) // prints doStuff
tryDoStuff(callback: callbackB) // prints doStuffSpecific

Upvotes: 1

Views: 364

Answers (1)

Alexander
Alexander

Reputation: 63271

Swift's overload resolution algorithm already prioritizes the most specific overload available. Here's an example:

typealias Callback<T> = (T) -> Void

protocol Protocol {}

struct A {}
struct B: Protocol {}

func doStuff<T>(callback: Callback<T>) {
    print("doStuff")
}

func doStuff<T: Protocol>(callback: Callback<T>) {
    print("doStuffSpecific")
}

let callbackA: Callback<A> = { _ in } // Just an empty closure
let callbackB: Callback<B> = { _ in }


doStuff(callback: callbackA) // prints doStuff
doStuff(callback: callbackB) // prints doStuffSpecific

Upvotes: 1

Related Questions