在本章中,我们将了解 Elixir 中 = 运算符为何称为匹配运算符,以及如何使用它在数据结构中进行模式匹配。我们将了解用于访问先前绑定的值的固定运算符 ^。
匹配运算符
我们在 Elixir 中多次使用了 = 运算符来分配变量:
在 Elixir 中,= 运算符实际上称为匹配运算符。让我们看看为什么:
请注意,1 = x 是一个有效表达式,并且它匹配是因为左侧和右侧都等于 1。当两侧不匹配时,会引发 MatchError。
只能在 = 的左侧分配变量:
模式匹配
匹配运算符不仅用于匹配简单值,还可用于解构更复杂的数据类型。例如,我们可以对元组进行模式匹配:
如果两侧无法匹配,例如元组大小不同,则会发生模式匹配错误:
在比较不同类型时也是如此,例如,如果将左侧的元组与右侧的列表进行匹配:
更有趣的是,我们可以匹配特定值。下面的例子断言,只有当右侧是以原子 :ok 开头的元组时,左侧才会与右侧匹配:
我们可以在列表上进行模式匹配:
列表还支持在其自己的头部和尾部进行匹配:
与 hd/1 和 tl/1 函数类似,我们无法将空列表与头部和尾部模式匹配:
[head | tail] 格式不仅用于模式匹配,还用于将项目添加到列表的前面:
模式匹配允许开发人员轻松解构元组和列表等数据类型。正如我们将在以下章节中看到的那样,它是 Elixir 中递归的基础之一,也适用于其他类型,例如映射和二进制文件。
固定运算符
Elixir 中的变量可以重新绑定:
但是,有时我们不希望变量重新绑定。
当您想要对变量的现有值进行模式匹配而不是重新绑定变量时,请使用固定运算符 ^。
由于我们在将 x 绑定到值 1 时将其固定,因此它等同于以下内容:
请注意,我们甚至会看到完全相同的错误消息。
我们可以在其他模式匹配(例如元组或列表)中使用固定运算符:
由于 x 在固定时绑定到值 1,因此最后一个例子可以写成:
如果一个变量在模式中被多次提及,则所有引用都必须绑定到相同的值:
在某些情况下,您并不关心模式中的特定值。将这些值绑定到下划线 _ 是一种常见的做法。例如,如果我们只关心列表的头部,我们可以将尾部分配给下划线:
变量 _ 的特殊之处在于它永远无法读取。尝试读取它会导致编译错误:
iex>_
** (CompileError) iex:1: invalid use of _. "_" represents a value to be ignored in a pattern and cannot be used in expressions
虽然模式匹配允许我们构建强大的构造,但其用法有限。例如,您不能在匹配的左侧进行函数调用。以下示例无效:
我们对模式匹配的介绍到此结束。正如我们将在下一章中看到的那样,模式匹配在许多语言构造中非常常见,并且可以通过保护进一步增强。