Swift - Assigning Overloaded Function to Variable

2020-03-02 04:43发布

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.

标签: swift
5条回答
一纸荒年 Trace。
2楼-- · 2020-03-02 05:24

Referencing func f (s: String) -> String { return "version 1: " + s }:

let myFunction = f(s:)

Referencing func f(sourceString s: String) -> String { return "version 2: " + s }:

let myFunction = f(sourceString:)

Referencing func anotherFunction(_ param: Any) {}:

let myFunction = anotherFunction(_:)

If you haven't overloaded the function, you don't need to explicity write out the parameter names when referencing the function.

查看更多
老娘就宠你
3楼-- · 2020-03-02 05:36

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"
查看更多
手持菜刀,她持情操
4楼-- · 2020-03-02 05:37

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.

查看更多
再贱就再见
5楼-- · 2020-03-02 05:43
  • Number of arguments should vary.
  • If the number of arguments are same then their data types should vary.

Example

func f(x : String) -> NSString {
        return a
    }
func f(x : UInt) -> NSString {
            return "{\(x)}"
        }
查看更多
Root(大扎)
6楼-- · 2020-03-02 05:44

I don't think you can. You can call one or the other:

println(f("test")) // version 1: test
println(f(sourceString: "test")) // version 2: test
查看更多
登录 后发表回答