【问题标题】:Swift - Assigning Overloaded Function to VariableSwift - 将重载函数分配给变量
【发布时间】:2015-02-02 19:08:18
【问题描述】:

我收到一个编译时错误,表明 myFunc 引用不明确。

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

如何在上面的示例中显式引用重载函数 f 的每个版本?如果我注释掉func f 的任何一个声明,它将编译并工作。但是我想知道如果两个函数都被声明了如何引用它们。谢谢。

【问题讨论】:

  • 如果我的回答对您有帮助,请告诉我。我可以尝试提供更多帮助

标签: swift


【解决方案1】:

我不知道该怎么做,但也许这会有所帮助:

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

您现在可以调用:

let s1 = myFunc1("one")  // returns "version 2: one"
let s2 = myFunc2("two")  // returns "version 1: two"

【讨论】:

  • 感谢您的回复,马科斯。我同意不超载,我避免了这个问题。当唯一的区别在于命名参数时,我对如何指定特定的函数签名更感兴趣。我的兴趣同样是学术性的(因为你提到的工作会奏效)。除了单独的名称之外,还有什么方法可以消除函数引用的歧义?
【解决方案2】:

这很有趣。如果不按照@marcos 的建议做一些事情,我认为这是不可能的。您的问题是您可以“抛弃”元组中的名称:

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'

现在假设你定义了两个函数,除了一个有命名参数之外,它们是相同的:

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

然后您可以通过带有命名和未命名参数的元组调用它:

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

但是因为你可以抛弃这些名字,你可以这样做:

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

据我所知,这种能力意味着不可能使用类型来消除仅由参数名称重载的函数的歧义。

【讨论】:

  • 感谢您的周到回复。所有人都对此进行了很好的讨论。空速速度——我很害怕。不是从实际的角度来看(我总是可以重命名函数以避免重载),而是从学术的角度来看。支持函数作为一等数据类型的语言似乎有点糟糕,其中存在无法明确引用重载函数的情况。好吧 - 我的学术很失望,但实用主义者会承认这可能几乎不会出现在“现实生活”中:-)
  • 我想到的另一种方法是将第二种方法声明为最初分配给变量的闭包。这也可行,但我真的希望该语言有一种方法可以引用包含命名参数消歧的函数签名。
【解决方案3】:

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

let myFunction = f(s:)

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

let myFunction = f(sourceString:)

引用func anotherFunction(_ param: Any) {}:

let myFunction = anotherFunction(_:)

如果你没有重载函数,你在引用函数时不需要显式写出参数名称。

【讨论】:

    【解决方案4】:
    • 参数的数量应该不同。
    • 如果参数的数量相同,那么它们的数据类型应该 变化。

    示例

    func f(x : String) -> NSString { 返回一个 } func f(x: UInt) -> NSString { 返回“{\(x)}” }

    【讨论】:

    • 不一定。 Swift 中的函数只允许在外部参数名称上有所不同。
    • 感谢@IvicaM。我不知道。
    【解决方案5】:

    我不认为你可以。您可以调用其中一个:

    println(f("test")) // version 1: test
    println(f(sourceString: "test")) // version 2: test
    

    【讨论】:

    • 谢谢,伊维卡。我调用每个函数都没有问题。但我想要一个对每个函数的变量引用(作为一等类型的函数,应该能够明确地将一个变量指向每个函数)。
    猜你喜欢
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 2018-01-24
    相关资源
    最近更新 更多