无法理解Play中Action方法的语法

时间:2017-12-23 12:15:37

标签: scala playframework

我怎样才能将代码块(而不是括号)传递给Action?我无法理解这种语法。我不应该使用()

val echo = Action { request =>
  Ok("Got request [" + request + "]")
} 

我认为ActionFunction1。 Scala中的以下示例使用(),因此Action{}的合作方式

object Main extends App {
   val succ = (x: Int) => x + 1 //create Function 1
   val anonfun1 = new Function1[Int, Int] { //create another Function1
     def apply(x: Int): Int = x + 1
   }
   assert(succ(0) == anonfun1(0)) //notice use of ()
}

我后来使用()代替{}进行了测试,但代码仍然有效。那么使用{}只能提高可读性吗?

val echo = Action ( request =>
  Ok("Got request [" + request + "]")
) 

2 个答案:

答案 0 :(得分:4)

看起来您需要阅读有关Scala的更多信息。

让我们先从基础知识开始,

scala> val a = 5
// a: Int = 5

此处,RHS仅为5,称为expression eiteralliteral expression

同样,Scala也允许,

scala> val a = { 5 }
// a: Int = 5

此处,RHS为{ 5 },称为block expression,此block评估为5

现在,让我们转到我们的用例

scala> object A {
     |   def apply(i: Int) = i + 5
     | }
// defined module A

现在,Scala允许我们以两种方式使用此A

val x1 = A(10)
// x1: Int = 15

// Or
val x2 = A { 10 }
// x2: Int = 15

为什么?看看Scala语言规范 - Functional Application

在这里,您将看到以下语法,

SimpleExpr    ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs ::=  ‘(’ [Exprs] ‘)’
                |  ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
                |  [nl] BlockExpr
Exprs         ::=  Expr {‘,’ Expr}

因此,如果我们使用()来应用函数,那么我们可以提供任何Expr(甚至多个),否则我们必须提供BlockExpr

现在,让我们谈谈你的例子(简化说明),

val echo = Action( request => Ok("") )

// VS

val echo = Action { request => Ok("") }

解析器解析它的方式存在差异。

第一个解析继续执行以下规则,

SimpleExpr        ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs     ::=  ‘(’ [Exprs] ‘)’
Exprs             ::=  Expr {‘,’ Expr}
Expr              ::=  (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr

如果第二个使用以下规则,

SimpleExpr        ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs     ::=  [nl] BlockExpr
BlockExpr         ::=  ‘{’ Block ‘}’
Block             ::=  BlockStat {semi BlockStat} [ResultExpr]
ResultExpr        ::=  (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Block             ::=  BlockStat {semi BlockStat} [ResultExpr]
BlockStat         ::=  Expr1

完整的解析树表达式,

enter image description here

答案 1 :(得分:1)

在Scala中,括号和花括号在各种场景中是可互换的,其中一个是函数参数列表中的包装()

def multiply(num: Int)(by: Int): Int = num * by

multiply(5)(2)
multiply{5}{2}

花括号语法还允许在内部写入多行表达式:

multiply{
  val num = 5
  num
}{
  val by = 2
  by
}
相关问题