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]
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号