jaf*_*don 15 scala function-literal
我总是想知道为什么有时使用函数文字我们可以忽略大括号,即使是多个语句.为了说明这一点,多行函数文字的语法是用大括号括起语句.像这样,
val fl = (x: Int) => {
println("Add 25 to "+x)
x + 25
}
Run Code Online (Sandbox Code Playgroud)
但是,当您将其传递给单参数函数时,您可以忽略函数文字所需的大括号.
所以对于给定的函数f,
def f( fl: Int => Int ) {
println("Result is "+ fl(5))
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样调用f(),
f( x=> {
println("Add 25 to "+x)
x + 25
})
-------------------------
Add 25 to 5
Result: 30
Run Code Online (Sandbox Code Playgroud)
或者在函数调用中使用花括号而不是括号时,可以从函数文本中删除内部花括号.所以下面的代码也可以,
f{ x=>
println("Add 25 to "+x)
x + 25
}
Run Code Online (Sandbox Code Playgroud)
上面的代码更具可读性,我注意到很多例子都使用这种语法.但是,是否有任何我可能错过的特殊规则,以解释为什么这样做符合预期?
som*_*ytt 24
只有几个简单的语法规则.该规范的附录值得细读.
函数文字或匿名函数(6.23)将看起来像x => Expr或x => Block取决于上下文是分别是Expr还是ResultExpr.
函数应用程序(6.6)看起来像f(Expr, Expr)或者f BlockExpr,即f{ Block }.也就是说,BlockExpr只是里面的一系列块语句{...}.
当你打电话时f(g),g是一个Expr,所以作为一个函数文字,x => Expr.Expr可以是BlockExpr , x => { ... }.
当你调用时f{ Block },f { x => ... }在块的ResultExpr中有函数文字(这只是一系列语句,不需要大括号).
在这里,很明显anon func位于块的底部:
scala> def m(x: Int=>Int) = x(5)
m: (x: Int => Int)Int
scala> m {
| val y = 7
| x => // no brace
| x+y+1
| }
res0: Int = 13
Run Code Online (Sandbox Code Playgroud)
wle*_*eao 11
这是让Scala对我很漂亮的事情之一.
你问题的简单答案是:
圆括号()用于单行构造.例如,这有效:
def f(fl: Int => Int) {
println("Result is " + fl(5))
}
f(
x =>
x + 25)
f(x => x + 25) // single line
Run Code Online (Sandbox Code Playgroud)
和花括号{}用于多行语句.例如,这有效:
f {
x =>
println("Add 25 to " + x)
x + 25
}
Run Code Online (Sandbox Code Playgroud)
但是这段代码不起作用:
f (
x =>
println("Add 25 to " + x)
x + 25
)
Run Code Online (Sandbox Code Playgroud)
编译器抱怨以下消息:
值x不是单位可能原因的成员:可能在"值x"之前缺少分号?
如果添加分号,则会出现由不匹配的括号引起的语法错误.
如果您尝试这样做:
f { x => println("Add 25 to " + x) x + 25 }
Run Code Online (Sandbox Code Playgroud)
编译器将通过以下消息回复您:
value x is not a member of unit
Run Code Online (Sandbox Code Playgroud)
你是否得到了他正试图找到x作为单位的成员.喜欢:
f { println("Add 25 to " + x).x.+(25) }
Run Code Online (Sandbox Code Playgroud)
这显然是错的.
如果你添加内花括号,像这样:
f (
x => {
println("Add 25 to " + x)
x + 25
}
)
Run Code Online (Sandbox Code Playgroud)
这也可以,但你仍然有一个多线语句,通过使用花括号来表示.所以编译器知道你想要的是先打印然后再添加25到x.
我之前被这些微妙之处所困扰.从那以后,我一直在关注我用这些编码的方式,因为当你主要使用map,flatMaps,foreachs,fors和currying时,你会编写代码并阅读很多内容.
干杯!
| 归档时间: |
|
| 查看次数: |
9909 次 |
| 最近记录: |