单语句单元函数的花括号的必要性

时间:2015-10-30 09:12:43

标签: scala return-type

我正在学习Scala并注意到,在风格上,有时候首选单语句函数不会被花括号括起来。为此,我进行了一些实验:

实验#1:

def func1(v: Vector[Int]) =
  for {n<-v; if n % 2 == 0 && n % 3 == 0 } yield n

val v = func1((1 to 10).toVector)
println(v)

函数体是单个表达式,恰好是一种理解。不需要花括号或返回类型规范。代码编译并生成输出Vector(6)

实验2:

def func2(s:String) =
  s + s

val s = func2("str")
println(s)

再次,一个表达式。不需要花括号或返回类型规范。代码编译并生成输出strstr

实验3:

这是事情变得棘手的地方:

var accum = "Begin "
def func3(arg:String)
    accum += arg // Cannot resolve symbol arg

代码无法编译,显示错误Cannot resolve symbol arg。很明显,Scala无法判断accum += arg行是func3的主体,当然,它会返回Unit。以下任一项都是编译器可接受的修复程序:

def func3(arg:String){
    accum += arg
}
func3("End")

此修复程序应用花括号。代码编译,生成输出Begin End

def func3(arg:String): Unit = 
    accum += arg
func3("End")

此修补程序不应用花括号,但指定func3的返回类型。代码编译,产生完全相同的输出。

那么这里发生了什么?为什么要求Unit - 返回单语句函数不能在语法上缩写?

2 个答案:

答案 0 :(得分:1)

来自scala规范

  

Scala是一种面向行的语言,其中语句可以用分号或换行符终止。 Scala源文本中的换行符被视为特殊标记“nl”   如果满足以下三个标准:

The token immediately preceding the newline can terminate a statement.
The token immediately following the newline can begin a statement.
The token appears in a region where newlines are enabled.

的情况下
def func3(arg:String)
    accum += arg

满足所有这三个条件。

浏览spec以查看详细信息。

答案 1 :(得分:0)

正如@Karthik在评论中提到的,我忽略了实验3 的第一种方法中的=。此外,@ johny向我指出了scala规范,我确定即使对于单语句函数或方法,也绝对需要一对花括号或=来使编译器理解我们正在定义一个方法