當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Elixir Stream用法及代碼示例


Elixir語言中 Stream 相關用法介紹如下。

用於創建和組合流的函數。

流是可組合的、惰性的可枚舉(有關可枚舉的介紹,請參閱 Enum 模塊)。在枚舉過程中一個一個地生成元素的任何可枚舉對象都稱為流。例如,Elixir 的 Range 是一個流:

iex> range = 1..5
1..5
iex> Enum.map(range, &(&1 * 2))
[2, 4, 6, 8, 10]

在上麵的示例中,當我們在範圍上進行映射時,被枚舉的元素是在枚舉過程中一一創建的。 Stream 模塊允許我們映射範圍,而不觸發其枚舉:

iex> range = 1..3
iex> stream = Stream.map(range, &(&1 * 2))
iex> Enum.map(stream, &(&1 + 1))
[3, 5, 7]

請注意,我們從一個範圍開始,然後我們創建了一個流,該流旨在將範圍中的每個元素乘以 2。此時,沒有進行任何計算。隻有當 Enum.map/2 被調用時,我們才真正枚舉範圍內的每個元素,將其乘以 2 並加 1。我們說 Stream 中的函數是 lazy Enum 中的函數是 eager

由於它們的惰性,流在處理大型(甚至無限)集合時很有用。當使用 Enum 鏈接許多操作時,會創建中間列表,而 Stream 創建稍後執行的計算配方。讓我們看另一個例子:

1..3
|> Enum.map(&IO.inspect(&1))
|> Enum.map(&(&1 * 2))
|> Enum.map(&IO.inspect(&1))
1
2
3
2
4
6
#=> [2, 4, 6]

請注意,我們首先打印列表中的每個元素,然後將每個元素乘以 2,最後打印每個新值。在此示例中,列表被枚舉了 3 次。讓我們看一個流的例子:

stream = 1..3
|> Stream.map(&IO.inspect(&1))
|> Stream.map(&(&1 * 2))
|> Stream.map(&IO.inspect(&1))
Enum.to_list(stream)
1
2
2
4
3
6
#=> [2, 4, 6]

雖然最終結果是一樣的,但元素的打印順序發生了變化!使用流,我們打印第一個元素,然後打印它的雙精度。在這個例子中,列表隻被枚舉了一次!

這就是我們之前所說的流是可組合的、惰性的枚舉的意思。請注意,我們可以多次調用 Stream.map/2 ,從而有效地組合流並使它們保持惰性。僅當您從 Enum 模塊調用函數時才會執行計算。

Enum 一樣,此模塊中的函數以線性時間工作。這意味著,執行操作所需的時間與列表長度的增長速度相同。這在諸如 Stream.map/2 之類的操作中是預期的。畢竟,如果我們要遍曆流上的每一個元素,流越長,我們需要遍曆的元素越多,需要的時間也就越長。

創建流

Elixir 的標準庫中有許多返回流的函數,例如:

該模塊還提供了許多用於創建流的便利函數,例如 Stream.cycle/1 Stream.unfold/2 Stream.resource/3 等。

請注意,此模塊中的函數保證返回可枚舉值。由於枚舉可以有不同的形狀(結構、匿名函數等),這個模塊中的函數可能會返回這些形狀中的任何一個,並且這可能隨時改變。例如,今天返回匿名函數的函數可能會在將來的版本中返回結構。

相關用法


注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 Stream。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。