调用匿名闭包

时间:2012-01-29 11:36:53

标签: scala closures invoke anonymous

修改
好的,这里的反馈很好,让我指出了正确的方向。用于调用匿名闭包的用例位于Scalatra路由层中。我有一堆路由在不同类型下组合在一起,在本例中,是团队共同的请求:

class Router {
  type TeamType <: _Controller with _Team

  get("""(schedules|rosters|teamresults|teamstats)/\d{8}""".r) {
    val clazz :: date = captures

    val obj = (clazz match {
      case "schedules" => new RosterController
      case "rosters" => new ScheduleController
    }).asInstanceOf[TeamType]

    obj.show(date)
  }
}

通过将匹配表达式包装在一个自调用的匿名闭包中,我们避免在每个匹配的情况下添加“FooController.asInstanceOf [TeamType]”,而是在返回的实例上执行类型转换,从而在过程中保持不变性(即不能“val obj = clazz match {...}”后跟类型cast as obj已经被val'd了)

我认为这是在基于字符串类名创建对象实例时可以获得的短格式。当然,这样说,可能有一种FP方法可以更加简洁地完成工作......

无论如何很酷的东西,都缺少来自Groovy的匿名闭包,现在我发现Scala也有这样的内容; - )

原始
不知道如何在Scala中解决这个问题。在Groovy中,您可以定义和调用匿名闭包,如下所示:

{String s-> println(s) }("hello")

Scala中的等价物是什么?另外,不是返回Unit,而是如何指定返回类型?

由于

2 个答案:

答案 0 :(得分:7)

((s : String) => println(s))("hello")

至于返回类型,让Scala推断它。

scala> ((x : Int) => x < 4)(3)
res0: Boolean = true

答案 1 :(得分:1)

要添加到@ larsmans的答案,您可以让Scala编译器推断出参数类型。 Scala类型推断从左向右流动,因此您必须相应地排列术语。我们可以通过定义管道转发运算符|>来实现这一点,这样:

x |> f = f(x)

它可以在Scalaz中使用。如果您不想使用Scalaz it's not hard to define it yourself

用法示例:

scala> "hello" |> { s => println(s) }
hello

scala> "hello" |> println
hello

scala> 3 |> { y => y < 4 }
res23: Boolean = true

scala> 3 |> { _ < 4 }
res24: Boolean = true