Erlang模式匹配错误

Erlang模式匹配错误,erlang,pattern-matching,Erlang,Pattern Matching,我最近开始学习Erlang,在尝试匹配时遇到以下错误 以下表达式工作正常: {A,_,[B|_],{B}}={abc,23,[22,x],{22}}. Resulting in A = abc B = 22 以下表达式不起作用: {A,_,[_|B],{B}}={abc,23,[22,x],{x}}. Is resulting in ** exception error: no match of right hand side value {abc,23,[22,x],{x}} 但是,如果

我最近开始学习Erlang,在尝试匹配时遇到以下错误

以下表达式工作正常:

{A,_,[B|_],{B}}={abc,23,[22,x],{22}}.
Resulting in
A = abc
B = 22
以下表达式不起作用:

{A,_,[_|B],{B}}={abc,23,[22,x],{x}}.
Is resulting in 
** exception error: no match of right hand side value {abc,23,[22,x],{x}}
但是,如果我将[22,x]中的“,”替换为a |,如下所示,它的工作查找和边界x到B

{A,_,[_|B],{B}}={abc,23,[22|x],{x}}.
{abc,23,[22|x],{x}}
B.
x
对此的任何解释都将不胜感激


提前非常感谢

您需要仔细了解
|
操作符是如何工作的。它基本上取列表的开头,这是一个元素,然后返回列表的结尾,这是所有其他元素。就像“all”一样,suggest tail也是一个列表。它可以是一个元素列表,甚至可以是空列表,但仍然是一个列表

> [Head| Tail] = [23,x].
[23,x]
> Head.
23
> Tail
[x].
因此,在模式匹配中,您指定为尾部
[x]
,然后尝试在
x
上进行模式匹配。这就是失败的地方

旁注:您可以使用
|
操作符创建新列表,但操作时应谨慎。因为您可以创建(并且可以使用
[23 | x]
),这就是“修复”起作用的原因

如果您想匹配两个元素列表,可以使用

[A, B] =  [23, x].
但若列表中有更多或更少的元素,则此操作将失败

如果只想在前两个元素上匹配,仍然可以使用
运算符

> [A, B | Rest] = [23, x].
[23, x]
> A.
23
> B.
x
> Rest.
[].

只有一个元素或空列表才会失败。

运算符
用于列表的递归定义:
[a | B]
意味着您将元素
A
添加到现有列表
B
A
是结果列表的第一个元素,称为head,
B
是列表的其余部分,称为tail。
B
也可以分为head和tail,该过程可以继续,直到tail等于空列表
[]

运算符是列表元素之间的分隔符,因此
[a,B]
是两个元素的列表
a
B

这两个操作符可以组合:
[A,B,C | D]
是至少包含3个元素的列表,分别是
A
B
C
,以及可以为空的尾部
D

在测试中,您使用了另一种语法:
[23 | x]
;23可以是列表的一个元素(实际上任何erlang术语都可以是列表的一个元素),但x是一个原子,不能是列表尾部。这样做会破坏列表的递归定义,这种结构不经常使用,被称为不正确的列表

  • 当您匹配
    [\u124; B]
    [\ux]
    时,您将
    [x]
    分配给表达式后面不匹配的
    B

  • 当您匹配
    [|B]
    [|x]
    时,您将
    x
    分配给
    B
    ,后者确实匹配表达式后面的
    x
    ,但正确的方法应该是

  • {A,{u124; B],{B}={abc,23,[22,x],{[x]}。


[| | Whatever]可以字面上指任何东西,因此它不能被匹配,因为
可以消耗/匹配任何东西,包括匹配的整个元素。这意味着“任何东西,后面跟着
任何东西,我们在这里不定义它”。
[22 | Whatever]
或任何
[FiniteThing |
的意思“一些具体和有限的东西,然后是
Whatever
”,可以匹配,因为它可以精确地匹配和使用列表的第一部分。瞧,“anything”匹配/使用所有东西,而一个特定和有限的东西只能代表它自己。非常感谢您的详细解释