Say I have a protocol Fooable
:
protocol Fooable {}
Now I need to work with a Fooable
type in a generic function:
func fooingAround<FooableType: Fooable>(withType: FooableType.Type) {}
This works fine when I just call the function with a Fooable
type:
struct Foo: Fooable {}
fooingAround(Foo.self) // works fine
However, I need to retrieve the Fooable
type that I hand over to the function from somewhere else. This is where the compiler fails:
let fooableType: Fooable.Type = // obtain from somewhere else
fooingAround(fooableType) // compiler error: "Cannot invoke 'fooingAround' with an argument list of type '(Fooable.Type)'"
Specifically, I obtain the Fooable.Type
from an enum that describes API endpoints, where each endpoint is represented by a different Fooable
class.
I suppose the problem arises because I dynamically obtain a type, so there can be no strong typing at compile time.
Is there a way to work around this?
The problem is that this:
let fooableType: Fooable.Type = // obtain from somewhere else
... is casting into oblivion precisely the information you want to store in that variable, i.e. what is the concrete type that is conforming to Fooable
. Consider that the following code compiles:
protocol Fooable {}
func fooingAround<FooableType: Fooable>(withType: FooableType.Type) {}
struct Foo: Fooable {}
fooingAround(Foo) // works fine
let foo = Foo()
let fooableType /* do not cast here */ = foo.dynamicType
fooingAround(fooableType) // also works fine
... which means that you have to find a way to directly pipe the type information into your function call without casting.
Depending on the sort of fooingAround
you have in mind, you may for example be able to extend Fooable
along the following lines:
extension Fooable {
func fooingAround() {
/* do some fooing with */ self.dynamicType // which is the Foo.Type when called on the `foo` value
}
}
foo.fooingAround()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With