【问题标题】:Is parameter evaluation order guraanteed in scala?scala中是否保证参数评估顺序?
【发布时间】:2018-11-20 22:00:32
【问题描述】:

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

【问题讨论】:

    标签: scala function parameter-passing


    【解决方案1】:

    评估顺序在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",即使afoo 的参数列表中出现在b 之前。确切的规则在6.6.1 "Named and default arguments" 中描述。

    回答关于您的具体示例的问题:fillArray(ba) 保证在ba 之前被评估,因此您的代码似乎没问题。实际上,在您的特定示例中,这并不重要,因为 ba 无论如何都是 val 。它在调用fillArray 前后指向同一个数组。

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      • 2011-12-17
      相关资源
      最近更新 更多