scala - 表示任何类型的匿名函数的语法

时间:2014-08-19 20:23:34

标签: scala syntax callback anonymous-function

我希望能够将回调函数作为参数传递给方法。现在,我可以传递签名() => Unit的功能,如

def doSomething(fn:() => Unit) {
  //... do something
  fn()
}
我认为这很好,但是我希望能够传递任何参数和任何返回类型的函数。

有没有这样做的语法?

由于

1 个答案:

答案 0 :(得分:0)

为了能够执行作为回调传递的函数,您必须能够使用它需要的参数来调用它。必须将f: A => R称为f(someA),并将g: (A,B) => R称为f(someA, someB)

实现一个回调,你想要一个接受上下文并返回一些东西的函数(你不关心它是什么)。例如,scala.Option中的foreach定义为:

def foreach[U](f: (A) => U): Unit

使用类型A的值调用函数但结果被丢弃,因此我们不关心它具有什么类型。或者,如果您不关心完成的内容,则可以将回调函数实现为:

def onComplete[U](f: () => U): Unit

然后允许使用任何不带参数的函数调用:

val f: () => Int = ...
val g: () => String = ...

onComplete(f) // In result is discarded
onComplete(g) // String result is discarded

如果你真的想要一个接受任何可能功能的功能,你可以使用一些技巧(但你真的不应该)。例如,您可以定义与隐式转换绑定的视图:

// Type F is any type that can be converted to () => U
def onComplete[F <% () => U, U](f: F): Unit

// Define conversions for each Function type to Function0
implicit def f1tof0[A,U](f: A => U): () => U = ...
implicit def f2tof0[A,B,U](f: (A,B) => U): () => U = ...
implicit def f3tof0[A,B,C,U](f: (A,B,C) => U): () => U = ...
.
.
etc.

现在onComplete接受任何功能:

val f: Int => String = ...
val g: (List[Int], String) => String = ...

onComplete(f)
onComplete(g)

定义上述转换的类型相对简单,但没有合理的方法来实现它们,所以几乎完全没用。