Reputation: 51153
The following compiles in the Swift REPL:
var m: [String:AnyObject] = [:]
func f<T: AnyObject>(s: String) {
m[s] = T.self
}
However, if I naively try to invoke f()
, thus:
let s: String = "foo"
class Foo {}
f<Foo>(s)
I get this error:
repl.swift:7:1: error: cannot explicitly specialize a generic function
f<Foo>(s)
^
repl.swift:7:2: note: while parsing this '<' as a type parameter bracket
f<Foo>(s)
^
If I try it without "explicitly specializing"...
f(s)
Swift decides I'm trying to do something even weirder, and I get:
repl.swift:7:1: error: cannot convert the expression's type 'String' to type '()'
f(s)
^~~~
Meanwhile, however, if I define a new function g()
as follows:
func g<T: AnyObject>(s: String, t: T) {
m[s] = T.self
}
and pass in a dummy Foo
instance:
g(s, Foo())
it works fine:
> m
$R0: [String : AnyObject] = {
[0] = {
key = "foo"
value = {
instance_type = {}
}
}
}
So is there a reason Swift lets me define f()
in the first place? And once defined, is there any way to invoke it?
ETA: I'm aware it's also possible to define a function h<T: AnyObject>(s: String, t: T.Type)
that takes the type explicitly. It's the fact that Swift allows me to define the implicit version that I find questionable.
Upvotes: 4
Views: 1400
Reputation: 72760
Differently from other languages, you cannot explicitly specify the generic type with a syntax like this:
f<Foo>(s)
instead the actual type is inferred via a parameter or the return type. In your case you are not providing a way for type inference to figure out what T
is. And sadly I'm not aware of any way to use that function.
My suggestion is to explicitly pass the type of T
:
func f<T: AnyObject>(s: String, type: T.Type) {
m[s] = type
}
...
f(s, Foo.self)
Upvotes: 4