如何在Scala中选择一组重载函数中的一个

时间:2013-06-14 19:22:11

标签: scala overloading

如何引用函数的一个重载?这需要反思吗?

----- Define two functions with the same signature

scala> def f( x:Int ) = x + 1
f: (x: Int)Int

scala> def g( x:Int ) = x + 2
g: (x: Int)Int

----- Define a function that returns one or the other

scala> def pick( a:Boolean ) = if (a) f _ else g _
pick: (a: Boolean)Int => Int

scala> pick(true)(0)
res24: Int = 1

scala> pick(false)(0)
res25: Int = 2

----- All good so far; now overload f to also take a String

scala> def f( x:String ) = x.toInt + 1
f: (x: String)Int

scala> def pick( a:Boolean ) = if (a) f _ else g _
pick: (a: Boolean)String with Int => Int

scala> pick(false)(0)
<console>:12: error: type mismatch;
 found   : Int(0)
 required: String with Int
              pick(false)(0)
                          ^

我理解为什么这不起作用。但是我如何定义pick以使用带有Int的f,并忽略带有String的f?

同样,我不想写一个调用f或g的函数。我想编写一个返回 f或g的函数,然后我可以调用gazillions。

2 个答案:

答案 0 :(得分:2)

只需添加类型注释:

def pick( a:Boolean ) = if (a) f(_: Int) else g(_: Int)

答案 1 :(得分:1)

补充:不要被REPL构造它运行的内容所迷惑:

scala> :pa
// Entering paste mode (ctrl-D to finish)

object Foo {
def f(i: Int) = i.toString
def f(s: String) = s
def pick( a:Boolean ) = if (a) f _ else "nope"
}

// Exiting paste mode, now interpreting.

<console>:10: error: ambiguous reference to overloaded definition,
both method f in object Foo of type (s: String)String
and  method f in object Foo of type (i: Int)String
match expected type ?
       def pick( a:Boolean ) = if (a) f _ else "nope"
                                      ^

使用REPL,你的问题的另一个答案是,定义你想要的那个,因为它变得最具体:

scala> def f(s: String) = s
f: (s: String)String

scala> def f(i: Int) = i.toString
f: (i: Int)String

scala> f _
res0: Int => String = <function1>