我创建了一个模块,如下所示:
defmodule Sum do
def sum(x,y) do
x + y
end
def sum(x) do
x
end
end
它的工作原理与我预期的模式匹配当然是:
iex(2)> Sum.sum(3)
3
iex(3)> Sum.sum(3,5)
8
当我定义匿名函数时:
iex(1)> sum = fn
...(1)> x, y -> x + y
...(1)> x -> x
...(1)> end
** (CompileError) iex:1: cannot mix clauses with different arities in function definition
然后编译器抱怨。为什么我不能与不同的arities混合,上面的例子与模块一样,它就像一个魅力。
答案 0 :(得分:11)
sum/2
和sum/1
实际上是两种不同的功能。执行的那个不是通过模式匹配来选择的。编译器根据您指定的参数数量知道要调用哪一个。
正如其他人所说,匿名函数可能有不同的子句,但它们必须具有相同的元素,因为您只是创建一个函数。
请考虑以下代码:
defmodule Sum do
def sum(x,y) where is_integer(y) do
x + y
end
def sum(x,_) do
x
end
end
这会创建单个sum/2
函数的2个子句,其中一个子句将由模式匹配和保护子句确定,如下所示:
iex> Sum.sum(3,nil)
3
iex> Sum.sum(3,5)
8
iex> Sum.sum(5,:foo)
5
你可以用匿名函数做同样的事情。
答案 1 :(得分:1)
看看这个先前的答案:
https://stackoverflow.com/a/18023790/2820
它准确地讨论了你的问题。你可以在lambda中有多个子句,但是所有子句都必须在arity中匹配。