Гарантирован ли порядок оценки параметров в scala? - PullRequest
0 голосов
/ 11 июня 2018

Я знаю, что это гарантированно будет выполняться слева направо в 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 голосов
/ 11 июня 2018

Порядок оценки описан в 6.6 «Приложения функций» .По сути, это то же самое, что и в 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 «Именованные аргументы и аргументы по умолчанию» .

Чтобы ответить на вопрос о вашем конкретном примере: fillArray(ba) гарантированно будет оцениваться до ba,так что ваш код кажется нормальнымНа самом деле, в вашем конкретном примере это не имеет большого значения, так как ba - это val в любом случае.Он указывает на один и тот же массив до и после вызова fillArray.

...