Elixir允许您使用Stream
s而不是Enum
s来防止集合的中间副本。但当你走到最后一步时,这有关系吗?
即使你得到了最小的细节,这不是吗
Stream.concat(header, rows)
|> CSV.encode
|> Stream.into(output)
|> Stream.run
和这个一样?
Stream.concat(header, rows)
|> CSV.encode
|> Enum.into(output)
如果是这样的话,为什么Stream.into/3
文档会提倡Stream.into
+Stream.run
的配对,而不仅仅是说Enum.into
?
也许这只是一个更容易阅读和发现的简单方法。
您的两个示例实际上并没有做相同的事情。第一个只是运行流管道,而第二个也会给你一个返回值。由于您没有使用结果,因此Stream.run
在这种情况下是可以的。
通常,如果您对流的结果感兴趣,您可以在管道的最后一步使用Enum
对应项。Stream.run
将而不是返回结果,而是应用管道,然后返回:ok
。如果您对副作用而不是实际返回值感兴趣,这将非常有用。
我想我们也有Stream.into
的原因是它可能而不是实际上是管道中的最后一步。这里有一个人为的例子:
output = IO.stream(:stdio, :line)
Stream.iterate(0, &(&1 + 1))
|> Stream.chunk(2, 1)
|> Stream.into(output, &"BEFORE: #{inspect &1}n")
|> Stream.map(fn [x, y] -> x * y end)
|> Stream.into(output, &"AFTER: #{inspect &1}n")
|> Stream.take(3)
|> Stream.run
哪个将输出
BEFORE: [0, 1]
AFTER: 0
BEFORE: [1, 2]
AFTER: 2
BEFORE: [2, 3]
AFTER: 6