2010-02-17 3 views

ответ

41

В элементах представления пересчитываются каждый раз, когда к ним обращаются. В элементах потока сохраняются по мере их оценки.

Например:

val doubled = List(1,2,3,4,5,6,7,8,9,10).view.map(_*2) 
println(doubled.mkString(" ")) 
println(doubled.mkString(" ")) 

будет переоценивать карту для каждого элемента в два раза. Один раз для первого println, и снова для второго. В отличие от этого

val doubled = List(1,2,3,4,5,6,7,8,9,10).toStream.map(_*2) 
println(doubled.mkString(" ")) 
println(doubled.mkString(" ")) 

будет удваивать элементы только один раз.

Вид, как рецепт для создания коллекции. Когда вы запрашиваете элементы представления, он каждый раз выполняет рецепт.

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

Если вы удерживаете первую карту (т. Е. Держите ссылку на головку потока), вы можете в конце концов выбежать из карт (т.е. памяти), когда вы попросите следующий элемент, но если вам не нужно вернитесь к первым элементам, которые вы можете отрезать струну и отдать ненужные карты обратно парню, и он может повторно использовать их (после этого они сохнут). Вот как поток может представлять бесконечную последовательность без исчерпания памяти.

+0

@huynhj у вас все в порядке. Я могу обновить ответ, чтобы сделать его более ясным. –

+1

вы можете оставить ответ как есть. Иногда метафора помогает. В этом случае я смутился этим. В первом же предложении было все. – huynhjl

+1

Пример строки очень запутан. – ziggystar

10

Geoff «s answer охватывает почти все, но я хочу добавить, что Stream является List -кака последовательности, в то время как каждый вид коллекции (карты, наборы, индексированный seqs) имеет вид.

+0

У меня есть одно сомнение. поскольку функция чиста. Почему компилятор не использует ссылочную прозрачность или memoization? Почему просмотр снова пересчитывает? –