我正在阅读出色的Joy of Elixir,并试图将模式匹配示例中的操作顺序包裹住。
我有清单
crew = [
%{name: "mal", age: 40},
%{name: "zoey", age: 36},
]
现在,我可以使用模式匹配来获取列表的第一个元素,并将名称分配给其他变量,例如
[first = %{name: first_name} | others] = crew
我了解到crew
中的第一个元素已分配给first
,而name
中的first
被分配给了first_name
:
iex> first
%{age: 40, name: "mal"}
iex> first_name
"mal"
根据示例,我还可以从右到左将名称分配给另一个变量:
%{name: first_name2} = first
但是当我从左到右尝试时,同样失败:
iex> first = %{name: first_name3}
** (CompileError) iex:33: undefined function first_name3/0
(stdlib) lists.erl:1354: :lists.mapfoldl/3
(stdlib) lists.erl:1355: :lists.mapfoldl/3
我的问题是:为什么列表匹配内的从左到右分配可以,但是列表匹配外的失败?
答案 0 :(得分:2)
首先评估=
(匹配运算符)的右侧。在表达式中
first = %{name: first_name3}
它试图获取first_name3
的值,但范围中没有first_name3
。
对于表达式
[first = %{name: first_name} | others] = crew
您可以将其视为
[first = %{name: first_name} = %{age: 40, name: "mal"} | others] = crew
或
others = tl(crew)
head = hd(crew)
first = %{name: first_name} = head
这是另一个例子:
x = "foo"
将变量x
绑定到字符串"foo"
(因为x
首先是未绑定的)。现在x
已绑定
到"foo"
,"foo" = x
也是有效的表达式,因为"foo"
与x
匹配。
答案 1 :(得分:1)
这是因为e剂评估序列的方式。当您启动IEX时,您的环境将是空的。当您输入first =%{name:first_name3}时,将从评估右侧开始。在实际的地图内部,您尝试将键“名称”与变量first_name3关联。如果您的环境中不存在first_name3,则表达式将无法求值,并且将出现未定义的函数错误。
这应该有效:
first_name3 = "John"
first = %{name: first_name3}