Elixir 关键词列表
2023-12-15 16:26 更新
在许多函数式编程语言中,经常用到一个由2值元组组成的列表,来表示一个联想数据结构。在Elixir中,当我们拥有一个由元组组成的列表,且元组第一个元素(键)是一个原子,那么我们称其为关键词列表:
iex> list = [{:a, 1}, {:b, 2}]
[a: 1, b: 2]
iex> list == [a: 1, b: 2]
true
iex> list[:a]
1
如你所见,Elixir支持用一种特殊语法来定义此类列表,它们实际上是元组列表的映射。由于它们也是列表,所以支持任何对列表的操作。例如,我们可以使用++来向关键词列表中添加新值:
iex> list ++ [c: 3]
[a: 1, b: 2, c: 3]
iex> [a: 0] ++ list
[a: 0, a: 1, b: 2]
注意往列表前添加的值会先被检索到:
iex> new_list = [a: 0] ++ list
[a: 0, a: 1, b: 2]
iex> new_list[:a]
0
关键词列表有三个重要特点:
- 键必须是原子
- 键的顺序是由开发者指定的
- 键可以被多次使用
例如,Ecto库利用这些特性提供了一个优雅的DSL用于书写数据库提问:
query = from w in Weather,
where: w.prcp > 0,
where: w.temp < 20,
select: w
这些特性使得关键词列表成为了Elixir中向函数传递设置的默认机制。在第五章,但我们讨论宏if/2
时,我们提到了下列语法:
iex> if false, do: :this, else: :that
:that
do:
和end:
组合都是关键词列表!事实上,上述调用等同于:
iex> if(false, [do: :this, else: :that])
:that
通常,当关键词列表是函数的最后一个参数时,方括号可以省略。
Elixir提供了Keyword
模块用于处理关键词列表。记住,关键词列表也是列表,具有和列表相同的线性性能特点。列表越长,寻找键和计算元素数量等等的时间就越长。因此,在Elixir中关键词列表只是备用选项。如果你想要存储很多元素,或保证一个键最多只与一个值相联系,那么你应该使用映射。
尽管我们可以对关键词列表进行模式匹配,但在实际中很少用到,因为它要求列表中的元素个数和顺序都要匹配:
iex> [a: a] = [a: 1]
[a: 1]
iex> a
1
iex> [a: a] = [a: 1, b: 2]
** (MatchError) no match of right hand side value: [a: 1, b: 2]
iex> [b: b, a: a] = [a: 1, b: 2]
** (MatchError) no match of right hand side value: [a: 1, b: 2]
以上内容是否对您有帮助:
更多建议: