我正在用 Elixir 写一个简单的例子,虽然它有效,但我并不真正理解如何。
defmodule MyList do
def sum([],acc \\ 0), do: acc
def sum([head | tail], acc), do: sum(tail,acc + head)
end
当我调用 MyList.sum 时,我得到了预期的结果
sum([]) => 0
sum([1,2,3]) => 6
我无法在第二个总和中添加默认参数,因为编译器抛出错误
def sum/2 has default values and multiple clauses, use a separate clause for declaring defaults
所以我的问题是, sum([1,2,3]) 是如何工作的?它不符合任何定义。
函数仍然是尾递归的吗?
最佳答案
当您有一个带有可选参数的多子句时,您可以将默认值指定为无正文子句:
defmodule MyList do
def sum(list, acc \\ 0) # sets up default arguments
def sum([],acc), do: acc
def sum([head | tail], acc), do: sum(tail,acc + head)
end
关于你的例子,我只是猜测,但我认为你的代码相当于以下内容:
defmodule MyList do
# implicitly generated due to default argument
def sum(list), do: sum(list, 0)
def sum([],acc), do: acc
def sum([head | tail], acc), do: sum(tail,acc + head)
end
这就是为什么
sum([1,2,3])
也有效。编辑 :
该函数绝对是尾递归的。如果一个函数做的最后一件事是调用另一个函数(或它本身),那么它就是尾调用。所以在这种情况下,当我们调用
sum(tail, acc + head)
,首先计算参数,然后发生尾递归调用。
关于recursion - Elixir 和默认参数中的尾递归调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22164902/