什么是Erlang中的模式匹配

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是Erlang中的模式匹配相关的知识,希望对你有一定的参考价值。

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

有人可以使用一个简单的解释向我解释什么是模式匹配。

任何人都能理解的解释。

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

答案

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

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

另一答案

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

模式匹配是如何在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将执行一些任务(!*!)以使双方匹配。你不能直接自己完成任务,你所能做的只是让erlang让事情匹配。如果这太令人困惑,那么只需将模式匹配运算符视为技巧赋值运算符,它比其他语言中的赋值运算符更强大。你在erlang中所谓的=标志并不重要,你只需要知道它是如何工作的。

在erlang中,模式匹配可以以多种不同的方式使用:

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

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

16> X.
10

17> Y.
1

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

my.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").

在shell中:

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中的模式匹配

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

与 Erlang 中的映射模式匹配时的非法表达式

为啥 OCaml 模式匹配比 Erlang 弱?

Erlang中的模式不匹配

Erlang 映射中的模式匹配键