串列 是 Elixir 中用來存放一組值的基本資料型態。串列是_不可變的_,意思是無法被修改。任何會改變串列的操作都會回傳新的串列。串列實作了 Enumerable 協定,因此可以使用 Enum 和 Stream 模組的函式。
Elixir 中的串列是以鏈結串列實作的,而不是連續記憶體位置的陣列。因此,存取串列中的元素需要線性時間,取決於串列的長度。
串列可以用字面形式、頭尾記法(使用cons運算子|),或兩者的組合來表示:
# Literal Form
[]
[1]
[1, 2, 3]
# Head-tail Notation
[]
# same as [1]
[1 | []]
# same as [1, 2, 3]
[1 | [2 | [3 | []]]]
# Mixed
# same as [1, 2, 3]
[1 | [2, 3]]
在 cons(|)運算子之前,也可以有一個以上的元素。
# Multiple prepends
[1, 2, 3 | [4, 5]]
頭尾記法可以用來把項目加到串列上。
list = [2, 1]
[3, 2, 1] == [3 | list]
# => true
在疊代的過程中把元素附加到串列上,被視為反面模式。附加元素需要走訪整個串列並把元素加到最後,因此,在每次疊代中都附加一個新元素,就代表每次疊代都得走訪整個串列。
我們可以先把元素加到反轉後的串列前面,再反轉結果,藉此達成相同的效果。把元素加到前面是很快的操作,只需要常數時間。
# Appending to the end of a list (potentially slow)
[1, 2, 3] ++ [4] ++ [5] ++ [6]
# Prepend to the start of a list (faster, due to the nature of linked lists)
[6 | [5 | [4 | [3, 2, 1]]]]
# then reverse!
Kernel 有幾個常見的串列相關函式:
hd/1 回傳串列的_頭部_,也就是串列中的_第一個_項目。tl/1 回傳串列的_尾部_,也就是串列_減去_第一個項目。length/1 回傳串列中的項目數量。in/2 回傳一個布林值,指出該項目是否為串列中的元素。另外還有 List 模組。
串列可以包含任何資料型態,也可以是不同資料型態的混合。
list = [1, :a, 2.0, "string"]