【问题标题】:Erlang function for()?Erlang 函数 for()?
【发布时间】:2018-09-13 10:23:47
【问题描述】:

据我了解,Erlang 不具备执行 for 循环的能力。然而,在这段代码 sn-p 中,它使用了 for() 函数。我不太了解这个 for() 函数,因此需要任何帮助。

-module(helloworld). 
-export([max/1,start/0]). 

max(N) -> 
   Max = erlang:system_info(process_limit), 
   io:format("Maximum allowed processes:~p~n" ,[Max]), 

   statistics(runtime), 
   statistics(wall_clock), 

   L = for(1, N, fun() -> spawn(fun() -> wait() end) end), 
   {_, Time1} = statistics(runtime),
   {_, Time2} = statistics(wall_clock),
   lists:foreach(fun(Pid) -> Pid ! die end, L),

   U1 = Time1 * 1000 / N, 
   U2 = Time2 * 1000 / N, 
   io:format("Process spawn time=~p (~p) microseconds~n" , [U1, U2]).

wait() ->
   receive 
      die -> void 
   end. 

for(N, N, F) -> [F()]; 
for(I, N, F) -> [F()|for(I+1, N, F)]. 

start()->
   max(1000), 
   max(100000).

另外,Erlang 中的 run time 和 wall_clock 有什么区别?我相信挂钟是基于计算机时钟,而运行时是基于 Erlang 中的某种滴答声?我可能错了

【问题讨论】:

    标签: for-loop time erlang


    【解决方案1】:

    我不太了解这个 for() 函数,因此请提供任何帮助。

    重命名函数 xyz()。现在,这有意义吗?

    xyz(N, N, F) -> [F()]; 
    xyz(I, N, F) -> [F()|xyz(I+1, N, F)].
    

    xyz() 函数的第一个子句查找相同 (N, N...) 的第一个和第二个参数。如果前两个参数相同,则xyz() 返回一个列表,其中包含调用第三个参数的返回值。

    当前两个参数不同(I, N, ...) 时,xyz() 函数的第二个子句将匹配。在这种情况下,调用第三个参数,它的返回值是列表的头部,列表的尾部是对 xyz() 函数的递归调用,其中第一个参数递增。

    那么,让我们尝试一个简单的例子:

    -module(f1).
    -compile(export_all).
    
    show() ->
       hello.
    
    
    xyz(End, End, F) -> [F()]; 
    xyz(Start, End, F) -> [F()|xyz(Start+1, End, F)].
    
    test() ->
        xyz(0, 5, fun show/0).
    

    在外壳中:

    5> c(f1).    
    f1.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,f1}
    
    6> f1:test().
    [hello,hello,hello,hello,hello,hello]
    

    这是另一个例子:

    for(End, End) ->
        io:format("~w~n", [End]); 
    for(Start, End) -> 
        io:format("~w~n", [Start]),
        for(Start+1, End).
    
    
    test() ->
        for(0, 5).
    

    在外壳中:

    12> c(f1).    
    f1.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,f1}
    
    13> f1:test().
    0
    1
    2
    3
    4
    5
    ok
    14> 
    

    【讨论】:

    • 啊,我明白了!它实际上只是一种实现 for 循环的递归方式。我现在感到困惑是愚蠢的。感谢您的快速指导!
    • @Alex.Smith,当然。基本上,您使用递归在 erlang 中编写自己的 for 循环,并根据您的特定需求定制循环。看起来您正在学习 Joe Armstrong 的“Programming Erlang”一书。如果您想将您的练习答案与我的比较,请参见此处:github.com/7stud/Programming-Erlang-Exercises-Solutions-Answers
    • 请问,您能解释一下为什么我们不能在函数中交换模式吗?我不明白为什么它不起作用: xyz(I, N, F) -> [F()|xyz(I+1, N, F)]; xyz(N, N, F) -> [F()].
    • @aleshka-batman,在您的示例中,参数变量 I、N、F 将匹配调用 xyz() 的任何三个参数,包括绑定到 I 的参数等于参数时绑定到 N,所以 erlang 从不计算第二个函数子句。要使您的示例正常工作,您必须添加一个守卫:xyz(I, N, F) when I /= N -> ...
    • ...Erlang 总是尝试按照编写顺序来匹配函数子句,因此 erlang 中函数子句的顺序很重要。该订单可用于您的优势,例如通过编写xyz(N,N,F),然后不必为第二个子句使用保护——erlang 只会在前两个参数不相等时评估第二个子句。这里有一个小测试:函数子句的顺序对函数定义是否重要:f(2) -> hello; f(X) -> goodbye.
    猜你喜欢
    • 2016-08-26
    • 1970-01-01
    • 2012-07-26
    • 2012-01-04
    • 2010-12-24
    • 2020-08-12
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多