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

时间:2018-06-11 15:32:10

标签: scala function parameter-passing

我知道它保证在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 Spec不能保证它?

1 个答案:

答案 0 :(得分:3)

评估顺序在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之前和之后的相同数组。