模式匹配可以用来解构复杂的数据结构:
=
等号操作符
- 解构时要求
=
左侧与右侧的数据类型相同 - 解构tuple,要求
=
左右的tuple中的元素个数相同# tuple 解构的常用场景 iex(21)> {:ok, result} = {:ok, [1, 2, 3]} {:ok, [1, 2, 3]} iex(22)> iex(10)> {a, b, c} = {:a, 1, "hello"} {:a, 1, "hello"} iex(11)> a :a iex(12)> b 1 iex(13)> c "hello" iex(14)> iex(15)> {a, b, c, d} = {:a, 1, "hello"} ** (MatchError) no match of right hand side value: {:a, 1, "hello"} iex(15)> {a, b, c, d} = {:a, 1, "hello", :d, :e} ** (MatchError) no match of right hand side value: {:a, 1, "hello", :d, :e}
- 解构list,与tuple相同,
=
左右两侧的数据长度相同iex(1)> [a, b, c] = [:a, 2, "hello"] [:a, 2, "hello"] iex(2)> a :a iex(3)> b 2 iex(4)> c "hello" iex(5)> # 匹配list的head和tail iex(5)> [head | tail] = [1, 2, 3, 4] [1, 2, 3, 4] iex(6)> head 1 iex(7)> tail [2, 3, 4] iex(8)>
^
pin操作符
使用了 ^
pin 操作符,在进行模式匹配时,只是进行比较,不会在给此变量重新付值
iex(1)> x = 1
1
iex(2)> x = 2
2
iex(3)> ^x = 3
** (MatchError) no match of right hand side value: 3
iex(3)> ^x = 2
2
iex(4)>
iex(8)> {^x, a} = {2, "a"}
{2, "a"}
iex(9)> a
"a"
iex(10)> x
2
iex(11)> {^x, a} = {"x", "a"}
** (MatchError) no match of right hand side value: {"x", "a"}
注意⚠️:模式匹配时,=
等式左侧不能是函数。
iex(2)> length([1, 2, 3]) = 3
** (CompileError) iex:2: cannot invoke remote function :erlang.length/1 inside a match
iex(2)> 3 = length([1, 2, 3])
3
iex(3)>
iex(12)> sum = fn a, b -> a + b end
#Function<41.3316493/2 in :erl_eval.expr/6>
iex(13)> sum.(1, 2) = 3
** (CompileError) iex:13: invalid pattern in match, anonymous call is not allowed in matches