var x = 1
def f(y:Int):Unit ={
x+=2
x*=3
}
var z = 4
f{
z = 5
6
} // <- 语法糖
x // 9
z // 5
Scala提供了一种很诡异的语法糖,
那就是当函数只需要一个参数的时候,就可以使用花括号进行调用。
In any method invocation in Scala in which you’re passing in exactly one argument, you can opt to use curly braces to surround the argument instead of parentheses.
1. Block
实际上,花括号以及所包含的表达式,构成了一个Block,
而Block的值,就是其中最后一个表达式的值。
A block expression
{s1; ……; sn; e}
is constructed from a sequence of block statementss1,…,sn
and a final expressione
.Evaluation of the block entails evaluation of its statement sequence, followed by an evaluation of the final expression
e
, which defines the result of the block.
因此,f{z=5; 6}
相当于f(6)
。
2. Call by name
var x = 1
def f(y: =>Int):Unit ={ // <- 修改 y 的类型为 =>Int
x+=2
x*=3
}
var z = 4
f{
z = 5
6
}
x // 9
z // 4 <- 不同
以上参数y
的类型为=>Int
,表明它是采用call-by-name方式调用的,
以下是Scala Language Specification v2.13 - 6.6 Function Applications对call-by-name的解释,
The case of a formal parameter with a parameterless method type
=>T
is treated specially. In this case, the corresponding actual argument expressione
is not evaluated before the application. Instead, every use of the formal parameter on the right-hand side of the rewrite rule entails a re-evaluation ofe
.In other words, the evaluation order for
=>
-parameters is call-by-name whereas the evaluation order for normal parameters is call-by-value.The behavior of by-name parameters is preserved if the application is transformed into a block due to named or default arguments. In this case, the local value for that parameter has the form val
y = () => e
and the argument passed to the function isy()
.
以上例子中,由于f
中未使用参数y
,因此,y
实际上没有被求值,
所以,z
的值还是4
。
3. Function vs Procedure
A function declaration has the form
def f psig: T,
wheref
is the function's name,psig
is its parameter signature andT
is its result type.A function definition
def f psig: T = e
also includes a function bodye
, i.e. an expression which defines the function's result.
Special syntax exists for procedures, i.e. functions that return the
Unit
value()
. A procedure declaration is a function declaration where the result type is omitted. The result type is then implicitly completed to theUnit
type. E.g.,def f(ps)
is equivalent todef f(ps): Unit
.A procedure definition is a function definition where the result type and the equals sign are omitted; its defining expression must be a block. E.g.,
def f(ps) {stats}
is equivalent todef f(ps): Unit = {stats}
.
参考
Programming in Scala
Scala Language Specification v2.13
Extending the curly-braces parameter list syntax
A Tour of Scala: Automatic Type-Dependent Closure Construction
Scala 自定义控制结构