почему переменная вычисляется после вызова в Scala - PullRequest
0 голосов
/ 15 мая 2018

Я попробовал свою программу https://scastie.scala -lang.org / RhCRxZkEQUqbC2gpiRtKnA

Моя программа:

val m = Map((1, "abc"), (2, "aaa"), (4, "aaaaaa"), (3, "a"), (5, "78"))
var mm :Map[Int, String] = Map.empty

val r = m.filterKeys { k =>
  if(k>3) true else {
    println(k)
    mm += (k -> m(k))
    false
  }
}

println("end of program", mm)

r // last line

Выход

(end of program,Map())
1
2
3

Если последняя строка r удалена, вывод будет

(end of program,Map())

Почему? любые намеки приветствуются. Спасибо

1 Ответ

0 голосов
/ 15 мая 2018

Документация API для Map.filterKeys гласит:

@ возвращает неизменную карту, состоящую только из тех пар значений ключа этой карты, где ключ удовлетворяет предикату p.Полученная карта оборачивает исходную карту без копирования каких-либо элементов.

Это означает, что filterKeys не начинает оценку с нетерпением, а вместо этого создает ленивое представление, которое скрывает некоторые ключи.Предикат не оценивается до тех пор, пока вы на самом деле не попытаетесь получить доступ к ключу, или, в этом случае, до тех пор, пока вы не выполните итерацию по карте.

Итерация инициируется методом toString.Метод toString в r вызывается REPL (в данном случае Scastie), как только вы пишете r, потому что он должен создать строковое представление результата.

Примечаниечто ничего не печатается, если вы запускаете ту же программу, что и сценарий: при запуске в качестве сценария не вызывается toString для промежуточных результатов, поэтому нет необходимости перебирать карту, и поэтому toString не вызывается.

...