[Scala] The curly-braces parameter

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.

——《Programming in Scala - P203》

1. Block

实际上,花括号以及所包含的表达式,构成了一个Block,
而Block的值,就是其中最后一个表达式的值。

A block expression {s1; ……; sn; e} is constructed from a sequence of block statements s1,…,sn and a final expression e.

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 expression e 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 of e.

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 is y().

以上例子中,由于f中未使用参数y,因此,y实际上没有被求值,
所以,z的值还是4

3. Function vs Procedure

A function declaration has the form def f psig: T, where f is the function's name, psig is its parameter signature and T is its result type.

A function definition def f psig: T = e also includes a function body e, i.e. an expression which defines the function's result.

—— 4.6 Function Declarations and Definitions

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 the Unit type. E.g., def f(ps)is equivalent to def 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 to def f(ps): Unit = {stats}.

—— 4.6.4 procedures


参考

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 自定义控制结构

你可能感兴趣的:([Scala] The curly-braces parameter)