Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - Assigning Overloaded Function to Variable

Tags:

swift

I am getting a compile time error that myFunc reference is ambiguous.

func f (s: String) -> String { return "version 1: " + s }
func f(sourceString s: String) -> String { return "version 2: " + s }
var myFunc: (String)-> String = f as (sourceString : String)->String

How can I explicitly reference each version of the overloaded function, f, in the example above? If I comment out either declaration of func f it will compile and work. But I would like to know how to reference each of the functions if both are declared. Thanks.

like image 900
Matt H Avatar asked Feb 02 '15 19:02

Matt H


2 Answers

I don't know how to do exactly what you want, but maybe this helps:

var myFunc1: (String)-> String = { s in f(sourceString: s) }
var myFunc2: (String)-> String = { s in f(s) }

You can now call:

let s1 = myFunc1("one")  // returns "version 2: one"
let s2 = myFunc2("two")  // returns "version 1: two"
like image 90
Marcos Crispino Avatar answered Oct 17 '22 21:10

Marcos Crispino


Interesting one this. I don’t think it’s possible without doing something along the lines of @marcos’s suggestion. The problem you is you can “cast away” the names in tuples:

let named_pair = (s: "hello", i: 1)
named_pair.s  // hello

let anon_pair = named_pair as (String,Int)
// or anon_pair: (String,Int) = named_pair, if you prefer
anon_pair.s  // no such member 's'

Now suppose you define two functions, identical except one has named arguments:

func f(s: String, i: Int) { println("_: \(s)") }
func f(#s: String, #i: Int) { println("s: \(s)") }

You can then call it via tuples with named vs unnamed arguments:

f(named_pair)  // prints s: hello
f(anon_pair)   // prints _: hello

// but if you try to call a named argument function with unnamed tuples:
func g(# s: String, # i: Int) { println("s: \(s)") }
g(anon_pair)  // compiler error

let h = g
h(anon_pair)   // compiler error
h(named_pair)  // works

But because you can cast away these names you can do this:

// compiles and runs just fine...
(g as (String,Int)->())(anon_pair)
let k: (String,Int)->() = g
// as does this
k(anon_pair)

And this ability to do this means it’s not possible to use a type to disambiguate an function overloaded only by argument names, as far as I can tell.

like image 32
Airspeed Velocity Avatar answered Oct 17 '22 19:10

Airspeed Velocity