我正在学习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
- 返回单语句函数不能在语法上缩写?
答案 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规范,我确定即使对于单语句函数或方法,也绝对需要一对花括号或=
来使编译器理解我们正在定义一个方法