像Erlang这种函数式编程语言,尾递归的使用对于减少栈开销是很重要的。尽管Erlang并不提倡防御式编程,但仍然提供了 try ... of ... catch ... after ... end 语句。这里有个需要注意的地方:try 语句模块里面的函数调用有可能无法形成尾递归。
下面是一个小实验:
1 -module(test). 2 -compile(export_all). 3 4 -define(LOOP_CNT, 10000000). 5 6 start_loop() -> 7 timer:tc(fun loop/1, [?LOOP_CNT]). 8 loop(N) when N =< 0 -> 9 erlang:process_info(erlang:self(), stack_size); 10 loop(N) -> 11 loop(N-1). 12 13 start_try_loop() -> 14 timer:tc(fun try_loop/1, [?LOOP_CNT]). 15 try_loop(N) when N =< 0 -> 16 erlang:process_info(erlang:self(), stack_size); 17 try_loop(N) -> 18 try try_loop(N-1) catch _:_ -> void end. 19 20 start_of_loop() -> 21 timer:tc(fun of_loop/1, [?LOOP_CNT]). 22 of_loop(N) when N =< 0 -> 23 erlang:process_info(erlang:self(), stack_size); 24 of_loop(N) -> 25 try N=N of _ -> of_loop(N-1) catch _:_ -> void end. 26 27 start_catch_loop() -> 28 timer:tc(fun catch_loop/1, [?LOOP_CNT]). 29 catch_loop(N) when N =< 0 -> 30 erlang:process_info(erlang:self(), stack_size); 31 catch_loop(N) -> 32 try N=e of _ -> void catch _:_ -> catch_loop(N-1) end.
实验结果印证了一开始的观点,仔细想想理应是这样的。
Erlang点滴--try语句里的尾递归,布布扣,bubuko.com
时间: 2024-10-12 18:40:03