Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中作为参数的多行函数文字_Scala_Function Literal - Fatal编程技术网

Scala中作为参数的多行函数文字

Scala中作为参数的多行函数文字,scala,function-literal,Scala,Function Literal,我一直想知道,为什么有时对于函数文字,即使对于多个语句,我们也可以忽略大括号。为了说明这一点,多行函数文字的语法是用大括号括住语句。这样, val fl = (x: Int) => { println("Add 25 to "+x) x + 25 } 但是,当您将其传递给单参数函数时,可以忽略函数literal所需的大括号 对于给定的函数f def f( fl: Int => Int ) { println("Result is "+ fl(5)) } 可以这样调用f

我一直想知道,为什么有时对于函数文字,即使对于多个语句,我们也可以忽略大括号。为了说明这一点,多行函数文字的语法是用大括号括住语句。这样,

val fl = (x: Int) => {
  println("Add 25 to "+x)
  x + 25
}
但是,当您将其传递给单参数函数时,可以忽略函数literal所需的大括号

对于给定的函数f

def f( fl: Int => Int ) {
  println("Result is "+ fl(5))
}
可以这样调用f()

f( x=> {
  println("Add 25 to "+x)
  x + 25
})
-------------------------
Add 25 to 5
Result: 30
或者在函数调用中使用大括号而不是括号时,可以从函数文本中删除内部大括号。所以下面的代码也可以工作

f{ x=>
  println("Add 25 to "+x)
  x + 25
}

上面的代码更具可读性,我注意到很多示例都使用这种语法。然而,是否有任何我可能错过的特殊规则,来解释为什么这是预期的工作

对我来说,这是斯卡拉美丽的原因之一

你的问题的简单答案是:

括号()表示单行结构。例如,这是有效的:

  def f(fl: Int => Int) {
    println("Result is " + fl(5))
  }

  f(
   x =>
    x + 25)

  f(x => x + 25) // single line
 f { 
   x =>
     println("Add 25 to " + x)
     x + 25
 }   
大括号{}用于多行语句。例如,这是有效的:

  def f(fl: Int => Int) {
    println("Result is " + fl(5))
  }

  f(
   x =>
    x + 25)

  f(x => x + 25) // single line
 f { 
   x =>
     println("Add 25 to " + x)
     x + 25
 }   
但是这个代码不起作用:

f ( 
  x =>
    println("Add 25 to " + x)
    x + 25
)
编译器发出以下消息:

值x不是单位的成员可能原因:可能是分号 在“值x”之前缺少

如果添加分号,将出现由不匹配的括号引起的语法错误

如果您尝试这样做:

f { x => println("Add 25 to " + x) x + 25 }
编译器将返回消息给您:

value x is not a member of unit
你知道他想找x作为单位的一员吗。比如:

f { println("Add 25 to " + x).x.+(25) }
这显然是错误的

如果添加内部花括号,如下所示:

f ( 
  x => {
    println("Add 25 to " + x)
    x + 25 
  }
)
这也会起作用,但您仍然有一个多行语句,它由大括号的使用来表示。因此,编译器知道您希望首先打印什么,然后将25添加到x

我以前也曾被这些微妙之处所折磨过。从那以后,我一直在关注我用它们编码的方式,因为当你主要使用地图、平面图、foreach、fors和currying时,你会编写和阅读大量的代码


干杯

这里只有几个简单的语法规则。规范的附录值得仔细阅读

函数文本或匿名函数(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中具有函数literal(这只是一个语句序列,不需要大括号)

在这里,很明显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

这就是我想要的解释。此外,除了突出显示的规格部分外,还可以参考块(6.11)部分以更好地理解。