How to call a generic Swift function when none of the arguments provides a generic type?

The following commands in Swift REPL:

var m: [String:AnyObject] = [:] func f<T: AnyObject>(s: String) { m[s] = T.self } 

However, if I naively try to call f() this way:

 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 being "explicitly specialized" ...

 f(s) 

Swift decides that I'm trying to do something even weirder, and I get:

 repl.swift:7:1: error: cannot convert the expression 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 to the dummy instance of Foo :

 g(s, Foo()) 

It works fine:

 > m $R0: [String : AnyObject] = { [0] = { key = "foo" value = { instance_type = {} } } } 

So, is there a reason Swift allows me to define f() in the first place? And once determined, is there a way to invoke it?




ETA: I know that it is also possible to define a function h<T: AnyObject>(s: String, t: T.Type) , which explicitly takes a type. It is a fact that Swift allows me to define an implicit version that I consider dubious.

+4
generics swift
Feb 25 '15 at 18:34
source share
1 answer

Unlike other languages, you cannot explicitly specify a generic type with syntax like this:

 f<Foo>(s) 

instead, the actual type is inferred through the parameter or return type. In your case, you do not provide a type inference method to figure out what T . And, unfortunately, I do not know how to use this function.

My suggestion is to explicitly pass type T :

 func f<T: AnyObject>(s: String, type: T.Type) { m[s] = type } ... f(s, Foo.self) 
+4
Feb 25 '15 at 18:42
source share



All Articles