Dictionary Elixir:模式匹配对元组和映射的效果不同

Dictionary Elixir:模式匹配对元组和映射的效果不同,dictionary,pattern-matching,tuples,elixir,Dictionary,Pattern Matching,Tuples,Elixir,在Elixir中,如果我尝试模式匹配以下两个元组: {a} = {1, 2} 我得到一个匹配错误。但如果我对两张地图也这样做: %{x: a} = %{x: 1, y: 2} 它工作正常,a绑定到1。我可以理解为什么匹配两个元组会产生错误,但为什么匹配映射不会产生错误 在第一个示例中,您试图将一个元素元组与一个两元素元组进行匹配。在第二个示例中,您将在左侧和右侧贴图中匹配:x键 编辑:我应该澄清Elixir中关于数据结构和模式匹配的规则 在元组上进行匹配时,需要提供与整个元组结构匹配的模式。

在Elixir中,如果我尝试模式匹配以下两个元组:

{a} = {1, 2}
我得到一个匹配错误。但如果我对两张地图也这样做:

%{x: a} = %{x: 1, y: 2}

它工作正常,
a
绑定到1。我可以理解为什么匹配两个元组会产生错误,但为什么匹配映射不会产生错误

在第一个示例中,您试图将一个元素元组与一个两元素元组进行匹配。在第二个示例中,您将在左侧和右侧贴图中匹配:x键

编辑:我应该澄清Elixir中关于数据结构和模式匹配的规则

在元组上进行匹配时,需要提供与整个元组结构匹配的模式。您可以使用
\uu
,这是“一网打尽”的模式,但仍然需要为元组的所有元素提供它。在列表上进行匹配时,必须使用
[a,b,c]=[1,2,3]
语法在所有元素上进行匹配,或者使用
[h | t]=[1,2,3]
语法在头部和尾部进行匹配。但是,在匹配映射时,可以在映射中的一个或多个键上进行匹配,这将为您提供
%{a:b}=%{a::foo,b::bar}
语法


数据结构之间的语义稍有不同,但都是相当常识。元组规则的存在是因为两个元组不能相同,除非它们具有相同数量的元素,列表具有相同的限制,但由于列表的语义,访问列表的头元素是使用它们时最常见的操作,因此使用
[h | t]
语法。但是,贴图可以基于特定的键进行匹配,因此元素的数量是不相关的,只要匹配的两边都包含相同的键和值的可选模式,那么它就是成功的匹配。

Maps
,Elixir中存储的主键值,有一个有趣的功能,使它们在模式匹配方面区别于其他数据结构

map
实际上可以仅在值的子集上进行模式匹配。模式中的键必须存在于匹配中,但这两个结构不必以
列表
元组
的相同方式相互镜像。例如:

iex(1)> [a, b] = [1, 2, 3]
** (MatchError) no match of right hand side value: [1, 2, 3]

iex(1)> {a, b} = {1, 2, 3}
** (MatchError) no match of right hand side value: {1, 2, 3}

iex(1)> %{:a => one} = %{:a => 1, :b => 2, :c =>3}
%{a: 1, b: 2, c: 3}
iex(2)> one
1
iex(3)> %{:a => one, :c => three} = %{:a => 1, :b => 2, :c =>3}
%{a: 1, b: 2, c: 3}
iex(4)> three
3
iex(5)> one
1
iex(6)> %{} = %{:a => 1, :b => 2, :c =>3}
%{a: 1, b: 2, c: 3}
iex(7)> %{:d => four} = %{:a => 1, :b => 2, :c =>3}
** (MatchError) no match of right hand side value: %{a: 1, b: 2, c: 3}

iex(8)> %{:a => one, :d => four} = %{:a => 1, :b => 2, :c =>3}
** (MatchError) no match of right hand side value: %{a: 1, b: 2, c: 3}
我们可以看到,如果模式的数据结构与匹配的数据结构(即大小)不同,则
列表
元组
都不匹配。然而,地图并非如此。因为密钥同时存在于模式和匹配中,所以无论模式和匹配的大小如何,匹配都是成功的。空的
映射也将匹配

但是,如果模式中的键不在匹配中,则匹配将不会成功。即使存在匹配的密钥,情况也是如此。因此,模式中使用的任何键都必须出现在匹配中

您将在Phoenix框架中广泛地看到这种匹配,以便仅从请求中获取必要的参数


资料来源:-

我明白了。需要明确的是,地图是唯一允许部分模式匹配的数据结构?是的,这是正确的。其他一切都需要模式匹配整个结构。不应该在上面:
%{x:a}={x:1,y:2}
be:
%{x:a}=%{x:1,y:2}
?@ericky是的,应该,我编辑了它。