是否在scala中保证了参数评估顺序?

问题描述 投票:2回答:1

我知道可以保证它在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规范无法保证?

scala function parameter-passing
1个回答
4
投票

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"的参数列表中的ab之前,也会打印foo。确切的规则在6.6.1 "Named and default arguments"中进行了描述。

要回答有关您的具体示例的问题:保证fillArray(ba)会在ba之前进行求值,因此您的代码似乎正常。实际上,在您的特定示例中,这并不重要,因为ba始终是val。在调用fillArray之前和之后,它指向相同的数组。

© www.soinside.com 2019 - 2024. All rights reserved.