Elixir 递归中的环
由于恒定性,Elixir中的环(与其他函数式编程语言一样)和命令式语言中的写法是不同的。例如,C语言中的写法是这样的:
for(i = 0; i < sizeof(array); i++) {
array[i] = array[i] * 2;
}
上述例子中,我们更改了数组和变量i。在Elixir中是不可更改的。所以函数式语言中以递归来替代:一个函数被反复调用,直到情况达到停止条件。在这个进程中没有数据被改变。思考下面的例子,一个字符串被打印任意次:
defmodule Recursion do
def print_multiple_times(msg, n) when n <= 1 do
IO.puts msg
end
def print_multiple_times(msg, n) do
IO.puts msg
print_multiple_times(msg, n - 1)
end
end
Recursion.print_multiple_times("Hello!", 3)
# Hello!
# Hello!
# Hello!
与case
类似,一个函数可以拥有许多从句。当传递来的参数与从句的参数模式相匹配并且其卫语句返回值为真,那么特定的从句就会被执行。
第一个从句的守卫说道“当且仅当n
小于或等于1
时使用这个定义”。由于不符合这个情形,Elixir继续到下一个从句定义。
第二个定义匹配模式成功,并且没有守卫,所以被执行了。它先打印了我们的msg
然后调用了他自己并传递了参数n-1 (2)
。
我们的msg
再次被打印,print_multiple_times/2
也再次被调用,这一次第二个参数被设置成了1
。由于n
已经被设置成1
了,print_multiple_times/2
的第一个定义中的卫语句执行结果为真,所以我们执行了这个定义。msg
被打印同时没有额外的语句需要执行了。
我们这样定义print_multiple_times/2
,无论第二个参数是什么数字,它不是触发了我们的第一个定义(被称为基本案例),就是触发了我们的第二个定义,并向基本案例更近了一步。
更多建议: