我知道可以保证它在Java中从左到右执行,但是Scala怎么样?我有一个方法可以接受数组和可读字节的限制:
def scanArray(limit: Int, ba: Array[Byte]) = { }
我也有一个方法,它接受一个数组,用一些数据填充它并返回它填充的字节数:
def fillArray(ba: Array[Byte]): Int = {...}
问题是可以按以下方式调用scanArray
:
val ba = new Array[Byte](16)
scanArray(fillArray(ba), ba)
行为得到保证吗?还是Scala规范无法保证?
6.6 "Function Applications"中描述了评估顺序。基本上,它与Java中的相同:
[f(e1,...,en)的求值通常需要按此顺序对f和e1,...,en进行求值。
即
({println("f"); (_: Int) + (_: Int)})(
{println("e1"); 40},
{println("e2"); 2}
)
将首先打印"f"
,然后打印"e1"
,然后打印"e2"
,最后计算f(e1, e2)
,即42
。
不过,此简单的基本规则并不适用于所有情况。例如,如果使用命名实参并更改这些实参的顺序,则重要的不是方法定义中的顺序,而是在调用站点传递命名实参的顺序。例如,
def foo(a: Int, b: Int): Unit = {}
foo(
b = { println("b"); 1 },
a = { println("a"); 2 }
)
将打印"b"
之前即使"a"
的参数列表中的a
在b
之前,也会打印foo
。确切的规则在6.6.1 "Named and default arguments"中进行了描述。
要回答有关您的具体示例的问题:保证fillArray(ba)
会在ba
之前进行求值,因此您的代码似乎正常。实际上,在您的特定示例中,这并不重要,因为ba
始终是val
。在调用fillArray
之前和之后,它指向相同的数组。