Elixir 初尝试 2 -- 模式匹配&等号&函数

啥模式匹配,不仅仅是正则?

谈到模式匹配,最开始很容易想到正则上面去,但是在Elixir里面,最基本的等号,以及函数调用都涉及到模式匹配。这到底是怎么回事呢?

等号和模式匹配

以等号为例,在前面简单说过,Elixir里面等号并不代表的是赋值,等号符号是匹配运算符(match operator),
如例子中所示

iex(1)> a=1
1
iex(2)> [x,y,_]=[2017.1,"hello","world"]
[2017.1, "hello", "world"]
iex(3)> x
2017.1
iex(4)> y
"hello"

并不是将右项赋值给左项,而是Elixir试图让等号左边等于等号右边,当等号两边的值以及数据结构完全匹配的时候,才算成功,这个过程叫做模式匹配。

函数和模式匹配

Elixir中最常见到的就是各种函数,下面是一个最简单的函数

iex(1)> swap = fn{a,b}-> {b,a} end
#Function<6.50752066/1 in :erl_eval.expr/5>
iex(2)> swap.({1,2})
{2, 1}

在调用函数swap的时候,如果是按照原来js或者java的思维,我们可以认为是将1赋值给a,2赋值给b。但Elixir中没有赋值的概念,实际上是对值进行模式进行模式匹配。

下面的例子更好的说明在函数调用时的函数匹配,反复出现的斐波那契数列在elixir的实现

defmodule Factorial do
 def of(0), do: 1
 def of(n), do: n*of(n-1)
end

是不是更清晰呀

模式匹配不够用,哨兵子句来凑

如果需要在函数调用的参数部分做更多的分支,单靠模式匹配根本不够。这个时候可以找下帮手——哨兵子句。
还是用那个用烂了的例子斐波那契数列,我们希望只对正数处理,当然你可以写成这种

defmodule Factorial do
 def of(0), do: 1
 def of(n), do: n>0&&n*of(n-1)||0
end

在计算部分加入判断的逻辑,还有一种如下

defmodule Factorial do
 def of(0), do: 1
 def of(n) when n>0, do: n*of(n-1)
end

这就是哨兵子句,在函数调用时,先执行模式匹配,在模式匹配通过的时候,哨兵子句的条件也满足的状况下,才会执行代码块。
模式匹配很好用,但也不是万能的。

相关推荐