2014-09-25 67 views
0

给定一个重载函数,以函数作为参数。此参数函数没有参数:Scala:带功能的重载函数作为参数

def func(param:() => Unit): Unit = { 
    param() 
} 

def func(param: Int): Unit = { 
    println(param) 
} 

在呼吁func一个匿名函数可以完美运行:

func(() => println("it works")) 

使用纯函数失败:

def functionAsParam(): Unit = { 
    println("it works") 
} 

func(functionAsParam) 

显然,斯卡拉评估functionAsParam并且不要将该函数本身传递给func。问题:我如何(作为提供func的库的用户)通过非匿名函数?

回答

2

有几种方法可以做到这一点。要么你明确地传递给函数的参数:

scala> func(() => functionAsParam) 
it works 

scala> func (functionAsParam _) 
it works 

(这两种情况略有不同,虽然,因为在第一个例子,你构造新的匿名功能与其他功能的读出,并在第二个例子中,你表明,这个功能应该还没有被添加_)

评估,或者你创建一个变量,它是一个函数,并沿着它传递:

val fval =() => println("It works") 
scala> func(fval) 
It works 
+1

我认为你的话不太正确,在parens。下划线的意思是“把我变成一个功能”。两种方式是一样的。不确定任何人都会使用第一种方式,但如果他们这样做了,他们会在调用风格时使用parens。 http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#method-values – 2014-09-25 21:30:56

+0

感谢您的评论,实际上那些以第一种方式做它的人是我,因为第二方式感觉不那么“直观”。 – Ashalynd 2014-09-25 22:32:28

2

错误来自您定义方法的事实,但您的func需要一个函数。是的,在scala中超载有问题(在其他方面也是如此)。要解决它,你需要手动的方法转换成一个功能(这就是所谓的ETA-expantion):

func(functionAsParam _) 

如果打开-Xprint:typer你会看到scalac扩展你的方法到一个函数:

val res4: Unit = func({ 
    (() => functionAsParam()) 
}); 
+0

第一个说法是错误的,因为它的工作原理没有过载。如果需要一个func,eta-expand会发生,但是如果不先选择一个重载的符号,就不能这么说。 – 2014-09-25 21:35:59