Во-первых, все они нестрогие. Это имеет особое математическое значение, связанное с функциями, но, по сути, означает, что они вычисляются по запросу, а не заранее.
Stream
действительно ленивый список. Фактически, в Scala Stream
— это List
, а tail
— это lazy val
. После вычисления значение остается вычисленным и используется повторно. Или, как вы говорите, значения кэшируются.
Iterator
можно использовать только один раз, потому что это указатель прохода в коллекцию, а не коллекция сама по себе. Что делает его особенным в Scala, так это тот факт, что вы можете применять преобразования, такие как map
и filter
, и просто получать новый Iterator
, который будет применять эти преобразования только тогда, когда вы запрашиваете следующий элемент.
Scala раньше предоставляла итераторы, которые можно было сбросить, но это очень сложно поддерживать в общем виде, и они не сделали версию 2.8.0.
Представления предназначены для просмотра так же, как представление базы данных. Это ряд преобразований, которые применяются к коллекции для создания «виртуальной» коллекции. Как вы сказали, все преобразования применяются повторно каждый раз, когда вам нужно извлечь из него элементы.
И Iterator
, и представления имеют отличные характеристики памяти. Stream
хорош, но в Scala его главное преимущество заключается в написании бесконечных последовательностей (особенно последовательностей, определяемых рекурсивно). Однако можно избежать хранения всех Stream
в памяти, убедившись, что вы не сохраняете ссылку на его head
(например, используя def
вместо val
для определения Stream
).
Из-за штрафов, налагаемых представлениями, обычно следует force
их force
после применения преобразований или оставить как представление, если ожидается, что когда-либо будет извлечено только несколько элементов по сравнению с общим размером представления.
person
Daniel C. Sobral
schedule
01.03.2011