什么是 Erlang 中的模式匹配

Posted

技术标签:

【中文标题】什么是 Erlang 中的模式匹配【英文标题】:What is Pattern Matching in Erlang 【发布时间】:2019-09-03 14:20:32 【问题描述】:

我正在学习 Erlang,遇到了模式匹配。

谁能用一个简单的解释向我解释什么是模式匹配。

任何人都可以理解的解释。

我已经阅读了多个来源,但仍然无法理解这个概念。

【问题讨论】:

很抱歉看到您的帖子被否决了,因为 SO 制定了问题质量标准。请参考此文档***.com/help/how-to-ask 作为您的问题,您可以查看这个 erlang 文档:erlang.org/doc/reference_manual/patterns.html 【参考方案1】:

考虑这个函数中的模式匹配示例:

Eshell V8.2.1  (abort with ^G)
1> F = fun(1, X) -> "hello f1";
1>        (2, X) -> "hello f2"
1>     end.
#Fun<erl_eval.12.52032458>
2> F(1, 33).
"hello f1"
3> F(2, some_token).
"hello f2"
4> F(3, "...").     
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(3,"...") 
5> 

与函数 F 的第一个参数的模式匹配可以执行代码分支或另一个。

模式匹配是一种方式:

保证满足部分条件 让代码进入一些特定的分支(如 if-then-else) 如果执行路径无效则引发错误

另见官方文档页面: http://erlang.org/doc/reference_manual/patterns.html

【讨论】:

【参考方案2】:

有人可以向我解释一下什么是模式匹配使用 简单的解释。任何人都可以理解的解释。

模式匹配是在 erlang 中发起的赋值方式。在其他语言中,= 符号是赋值运算符,例如x = 10。但是,在 erlang 中,= 符号是 模式匹配运算符。当 erlang 看到 = 符号时,它会查看 = 符号右侧的项,然后尝试为等号左侧的变量赋值,以便= 符号相同,即它们匹配。

在简单的情况下,例如X = 1,看起来 = 符号在 erlang 中执行赋值。事实上,X 在评估该语句后将具有值1。但是,您不能用其他语言编写以下内容:

 Y, 10 = 20, 10

在其他语言中,赋值运算符的左侧不能有常量。然而,在 erlang 中,在 模式匹配运算符 左侧指定常量是完全正常的。在评估该语句之后,Y 将具有值 20,因为为了使 = 符号的两侧相同,erlang 必须将值 20 分配给 Y。

erlang 如何执行该任务?这并不重要,但您可以将erlang中的赋值运算符视为三个字符!*!。当erlang看到上例中的模式匹配操作符时,为了得到匹配,erlang使用赋值操作符!*!将值20赋值给Y,即Y !*! 20

当你在 erlang 中写 = 时,你是在问,“请尝试让这些东西匹配!”。连锁反应是 erlang 将执行一些分配 (!*!) 以使双方匹配。你不能自己直接做assignment,你能做的就是让erlang让事情匹配。如果这太令人困惑,那么只需将模式匹配运算符视为一个技巧赋值运算符,它比其他语言中的赋值运算符更强大。 erlang 中的= 登录名不管你叫什么,你只需要知道它是如何工作的。

在erlang中,模式匹配有很多不同的用途:

1) 从数据结构中提取位置值:

15> [X, Y, _] = [10, 1, hello].
[10,1,hello]

16> X.
10

17> Y.
1

2) 确定在函数定义中执行哪个函数子句:

我的.erl:

    go(X, hello) ->
        io:format("Do stuff: ~w~n", [X*2]);
    go(X, goodbye) ->
        io:format("Do other stuff: ~w~n", [X-2]);
    go(_, _) ->
        io:format("Okay.~n").

在外壳中:

7> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
ok,my

8> my:go(3, 4).  
Okay
ok

9> my:go(2, goodbye).
Do other stuff: 0
ok

10> my:go(10, hello).
Do stuff: 20
ok

在第一个函数调用中,erlang 执行以下模式匹配:

X, hello = 3, 4

...失败是因为 erlang 无法将 (!*!) 分配给 X 的值会使双方都匹配。因此,erlang 继续执行下一个函数子句并执行匹配:

X, goodbye = 3, 4

这也失败了;最后,第三个函数子句匹配,因此该函数子句主体中的语句执行。

3)案例陈述、列表推导等

【讨论】:

以上是关于什么是 Erlang 中的模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

模式匹配是首选还是惯用 Erlang 中的 case 语句?

为啥 Erlang 中的模式匹配记录会抛出错误

为啥 OCaml 模式匹配比 Erlang 弱?

Erlang中的模式不匹配

Erlang 映射中的模式匹配键

Erlang函数与模式匹配