Что ленивого в взглядах на изменчивые коллекции Scala? - PullRequest
3 голосов
/ 26 мая 2019

Я думаю, что этот вопрос в основном о том, что лень в контексте изменчивости.

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

[ transformer методы] принимают по крайней мере одну коллекцию в качестве объекта-получателя и создают другую коллекцию в своем результате.... A view - это особый вид коллекции, которая представляет некоторую базовую коллекцию, но лениво реализует все ее преобразователи.

Они приводят примеры с неизменяемыми коллекциями, и я понимаю, кактам работает леньНо я борюсь с ролью, которую играет лень в примере с изменяемой коллекцией:

Многие функции-преобразователи в [просмотрах изменяемых последовательностей] предоставляют окно в исходную последовательность ... пример...

val arr = (0 to 9).toArray
val subarr = arr.view.slice(3, 6)

Представление не копирует эти элементы, оно просто предоставляет ссылку на них.

def negate(xs: collection.mutable.Seq[Int]) = 
  for (i <- 0 until xs.length) xs(i) = - xs(i)

negate(subarr)
arr  // Array(0, 1, 2, -3, -4, -5, 6, 7, 8, 9)

Я понимаю, почему мы получаемэтот ответ.Но что ленивого в трансформаторе slice?Я понял, что лень означает, что значения вычисляются только при необходимости (как в примерах с неизменяемыми коллекциями).Но значения в slice никогда не вычисляются, это просто ссылки на значения в arr, даже после вызова negate.Это мое непонимание лени?Или в документах лень по-другому?Или что-то еще?

1 Ответ

0 голосов
/ 27 мая 2019

Вот лучший пример такого ленивого поведения:

val a = Array(1,2,3)
val b = a.map(_ + 5)
val c = a.view.map(_ + 5)
println(b(1)) //prints 7
println(c(1)) // prints 7

a(1) = 5

println(b(1)) // still prints 7, since that array was computed on instantiation
println(c(1)) // now prints 10, since elements of c are lazily evaluated each time.
...