我目前正在学习长生不老药,我想知道这三个实现是否真的是一个选择问题,或者是否存在与性能或其他方面相关的最佳实践,换句话说,是否有最佳实践?
我的第一个实现是第三个(...我知道),但是如果必须选择,我一定会选择第二个。第一个对我来说似乎很奇怪,因为我定义了3次函数
谢谢 !
@spec count(list) :: non_neg_integer
def count(l), do: count(l, 0)
defp count([], acc), do: acc
defp count([_ | tail], acc), do: count(tail, acc + 1)
@spec count(list) :: non_neg_integer
def count(l) do
case l do
[] -> 0
[_|tail] -> 1 + count(tail)
end
end
@spec count(list) :: non_neg_integer
def count(l) do
do_count(l, counter)
end
defp do_count(list, counter \\ 0) do
cond do
list == [] -> counter
true ->
counter = counter + 1
do_count(tl(list), counter)
end
end
最佳答案
我想知道这三个实现是否真的是一个选择问题,或者是否有一些与性能或其他事情相关的最佳实践,换句话说,有没有最佳实践?
它们之间的一个重要区别是第一个和第三个实现是tail recursive,而第二个则不是。这意味着第二种实现将使用O(n)
内存对元素的n
列表执行,而第一种和第三种实现将使用O(1)
。
第三种解决方案使用cond
,其中模式匹配解决方案本来会更短,而且很可能会更快。
你可以重写
cond do
list == [] -> counter
true ->
counter = counter + 1
do_count(tl(list), counter)
end
至
case list do
[] -> counter
[_|tail] ->
counter = counter + 1
do_count(tail, counter)
end
与第一个实现几乎相同。
第一个绝对是三个中最惯用的,而且很可能是最快的。
关于elixir - 这些不同的功能定义的优缺点是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36871202/