Scala方法调用中的花括号

5
在Scala中,我们可以这样写:

println { "Hello, world!" }

来自《Programming in Scala》一书的内容:

将花括号替换为圆括号来传递一个参数的目的是为了使客户端程序员能够在花括号之间编写函数字面量。这可以使方法调用感觉更像控制抽象。

这句话的意思是什么?

在这里发布了:https://users.scala-lang.org/t/curly-braces-in-scala-method-call/2588 - Mandroid
4个回答

15

这只是为了视觉效果而存在的语法糖。当一个函数像下面这样接受一个函数作为参数时:

def doWith[A, B](todo: A => B): B = ???

通常情况下,您需要像这样调用它:

doWith( input => ... )
// or even
doWith({ input => ... })
在Scala中,允许用花括号 `{}` 替换圆括号 `()`。
doWith { input =>
  ...
}

具有控件结构的外观和感觉,例如

if (...) {
  ...
}

个人认为,这使得调用高阶函数如“map”或“collect”更易读:

someCollection.map { elem =>
  ...
  ...
}

这本质上与

someCollection.map({ elem =>
  ...
  ...
})

更节省字符。


请注意,分号推断发生在 {} 之间,而不是 () 之间。 - Seth Tisue
有没有办法使用val而不是def来使这个工作?https://dev59.com/-rTna4cB1Zd3GeqPBd4T - Thilo
1
@Thilo 在那里回答了。 - Alexey Romanov

3
"控制抽象",例如ifwhile等。因此,您可以编写一个函数。
def myIf[A](cond: Boolean)(ifTrue: => A)(ifFalse: => A): A = 
    if (cond) ifTrue else ifFalse

(如果您不熟悉:=> Type语法,请搜索“按名称的参数”)您可以这样调用
val absX = myIf(x < 0) { -x } { x }

看起来非常类似于普通的if调用。当然,仅当您编写的函数与现有控制结构更不同时,这会更加有用。


2
除了(常规)函数和按名称传递的参数外,大括号还有助于处理局部函数:
processList(l) {
  case Nil => ...
  case h :: t => ...
}

以及表达式的序列:

doSomething {
  thing1;
  thing2
}

请注意,在Scala中(thing1; thing2)不是有效的表达式,就像在ML中一样。

1

花括号 {} 和圆括号 () 的区别在于,你可以在花括号中写多行代码,而在圆括号中你不能写超过一行的代码。

val x :[List[Int]]=List(1,2,3,4,5,6,7,8)
x.map(y=> y*5) //it will work fine
x.map(y=> 
case temp:Int=>println(temp)
case _ => println(“NOT Int”)) //it will not work

x.map{y=> 
case temp:Int=>println(temp)
case _ => println(“NOT Int”)} //it willwork

因此,我们可以说它只是一种合成糖,让开发人员在没有分号的情况下编写多行代码。 这可能也有其他原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接