我怎样才能将代码块(而不是括号)传递给Action
?我无法理解这种语法。我不应该使用()
val echo = Action { request =>
Ok("Got request [" + request + "]")
}
我认为Action
是Function1
。 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 + "]")
)
答案 0 :(得分:4)
看起来您需要阅读有关Scala的更多信息。
让我们先从基础知识开始,
scala> val a = 5
// a: Int = 5
此处,RHS仅为5
,称为expression eiteral
或literal 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
完整的解析树表达式,
答案 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
}