0%

Elixir基础笔记(五)—— 模块与函数

在Elixir中,模块可以简单的理解为多个函数的集合,可以使用defmodule宏来创建。例如我们之前使用过的String 模块

1
2
3
4
5
6
7
8
iex> defmodule Math do
...> def sum(a, b) do
...> a + b
...> end
...> end

iex> Math.sum(1, 2)
3

函数

在模块中我们可以通过def/2defp/2来定义函数与私有函数。私有函数只能在该模块内进行调用

1
2
3
4
5
6
7
8
9
10
11
12
defmodule Math do
def sum(a, b) do
do_sum(a, b)
end

defp do_sum(a, b) do
a + b
end
end

IO.puts Math.sum(1, 2) #=> 3
IO.puts Math.do_sum(1, 2) #=> ** (UndefinedFunctionError)

函数同样支持守卫(guards)和多个分句。如果一个函数有多个分句,Elixir会依次进行匹配直到找到符合的为止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
defmodule Math do
def zero?(0) do
true
end

def zero?(x) when is_integer(x) do
false
end
end

IO.puts Math.zero?(0) #=> true
IO.puts Math.zero?(1) #=> false
IO.puts Math.zero?([1, 2, 3]) #=> ** (FunctionClauseError)
IO.puts Math.zero?(0.0) #=> ** (FunctionClauseError)

同样的,如果你的函数比较短的话,可以写成下面这样

1
2
3
4
defmodule Math do
def zero?(0), do: true
def zero?(x) when is_integer(x), do: false
end

&操作符与匿名函数

让我们先看一个例子

1
2
3
4
5
6
7
8
iex> Math.zero?(0)
true
iex> fun = &Math.zero?/1
&Math.zero?/1
iex> is_function(fun)
true
iex> fun.(0)
true

从上面的例子我们可以看到,常规的函数与匿名函数相比最大的不同是匿名函数需要在变量括号前加一个.。而上面的&操作符叫做捕获操作符(capture operator)。除此之外,&还可以用来创建函数。

1
2
3
4
5
6
7
8
9
iex> fun = &(&1 + 1)
#Function<6.71889879/1 in :erl_eval.expr/5>
iex> fun.(1)
2

iex> fun2 = &"Good #{&1}"
#Function<6.127694169/1 in :erl_eval.expr/5>
iex)> fun2.("morning")
"Good morning"

&1代表函数里的第一个变量,同理&2,&3代表函数的第二个变量,第三个变量(如果有的话)。上面&(&1 + 1)fn x -> x + 1 end是完全一样的。

关于&的更多介绍可以查看Kernel.SpecialForms的文档

函数的默认值

默认值跟在变量后面用\\隔开。

1
2
3
4
5
6
7
8
defmodule Concat do
def join(a, b, sep \\ " ") do
a <> sep <> b
end
end

IO.puts Concat.join("Hello", "world") #=> Hello world
IO.puts Concat.join("Hello", "world", "_") #=> Hello_world

欢迎关注我的其它发布渠道