Erlang 等价于C++;,while循环?

Erlang 等价于C++;,while循环?,erlang,while-loop,counter,increment,Erlang,While Loop,Counter,Increment,递增/递减运算符是否有等效表达式,例如计数器+++? 我还想知道如何正确地做到这一点 -module(whileloop). -export([call/0, while_loop/2]). call() -> while_loop(10,0). while_loop(Var,Counter) -> case Var =:= Counter of false -> Counter += 1,

递增/递减运算符是否有等效表达式,例如计数器+++? 我还想知道如何正确地做到这一点

-module(whileloop).
-export([call/0, while_loop/2]).

call() ->
    while_loop(10,0).

while_loop(Var,Counter) ->  
    case Var =:= Counter of
        false ->
            Counter += 1,
            whileloop(Var);
    end.
编辑:


只要递归调用
while_loop
,将
计数器
参数递增一:

while_loop(Var, Counter + 1)

只要递归调用
while_loop
,将
计数器
参数递增一:

while_loop(Var, Counter + 1)

C+=1的含义是修改C的值。它在Erlang中是无意义的,因为它只能给出以下结果:

1> C = C+1.
* 1: variable 'C' is unbound
C = 1.
1
3> C = C+1.
** exception error: no match of right hand side value 2
请记住,“A=B”并不意味着将B的值分配给A,而是将A与B进行“模式匹配”

  • 如果A未绑定,则它将绑定到A,值为B
  • 如果A=:=B未执行任何操作,则进程将继续
  • 如果A=/=B,则进程崩溃
所以,是的,若你们想要一个计数器,或者任何改变的信息,你们必须使用一个状态变量,作为递归循环的参数传递。从这个角度来看,您的上一个代码是正确的,但是让我们看看在shell中调用“call()”时会发生什么

首先,它在同一个进程中(shell)调用函数while_loop(10,0)

10不等于0,因此它在_循环(10,1)时立即调用

10不等于1,因此它在_循环(10,2)时立即调用

依此类推,直到它调用while_循环(10,10)。现在10=:=10是真的,并且这个结果与案例中的任何子句都不匹配,因此您会得到一个错误,进程会崩溃

由于您的代码不包含任何消息接收,只需循环一个循环直到崩溃,因此wole过程只需几微秒,因此看起来它会立即失败

根据您的期望,您可以想象几种类型的计数器,以下是两个示例:

-module(counter).

-compile(export_all).

% one counter that help you to count some events

% interface

start_c1(End) when is_integer(End) ->
    spawn(?MODULE,counter1,[End]).

start_link_c1(End) when is_integer(End) ->
    spawn_link(?MODULE,counter1,[End]).

inc_c1(Pid) when is_pid(Pid) ->
    Ref = make_ref(),
    Pid ! {inc,self(),Ref},
    receive
        {Ref,done} -> done;
        {Ref,V} -> V
    after 1000 ->
        {error,no_response}
    end.

value_c1(Pid) when is_pid(Pid)  ->
    Ref = make_ref(),
    Pid ! {get_value,self(),Ref},
    receive
        {Ref,V} -> V
    after 1000 ->
        {error,no_response}
    end.

stop_c1(Pid)  when is_pid(Pid) ->
    Pid ! stop.

% the counter

counter1(End) -> counter1_loop(End,0).

counter1_loop(End,V) ->
    receive
        {inc,Pid,Ref} when V =/= done -> 
            NewV = case V+1 of
                End -> done;
                Nv -> Nv
            end,
            Pid ! {Ref,NewV},
            counter1_loop(End,NewV);
        {inc,Pid,Ref} ->
            Pid ! {Ref,done},
            counter1_loop(End,done);         
        {get_value,Pid,Ref} ->
            Pid ! {Ref,V},
            counter1_loop(End,V);
        stop ->
            ok
    end.

% One kind of timeout that execute something after a while - 
% note it exists a similar one in the library

start_after(T,M,F,A) when is_integer(T), is_list(A) ->
    Ref = make_ref(),
    {Ref,spawn(?MODULE,after_receive,[T,M,F,A,self(),Ref])}.

cancel_after(P) when is_pid(P) ->
    P ! cancel.


% the counter
after_receive(T,M,F,A,Pid,Ref) ->
    receive
        {cancel,Ref} -> Pid ! {after_receive,Ref,cancelled}
    after T ->
        Pid ! {after_receive,Ref,done},
        apply(M,F,A)
    end.
下面是如何使用它们:

1> c("../src/counter").
{ok,counter}
2> {Ref,P} = counter:start_after(5000,io,format,["This is the end!" ]).
{#Ref<0.0.0.29>,<0.33.0>}
This is the end!3> 
3> {Refa,Pa} = counter:start_after(50000,io,format,["This is the end!" ]).
{#Ref<0.0.0.34>,<0.35.0>}
4> Pa ! {cancel,Refa}.
{cancel,#Ref<0.0.0.34>}
5> flush().
Shell got {after_receive,#Ref<0.0.0.29>,done}
Shell got {after_receive,#Ref<0.0.0.34>,cancelled}
ok
6> P1 = counter:start_c1(5).
<0.52.0>
7> counter:inc_c1(P1).
1
8> counter:inc_c1(P). 
{error,no_response}
9> counter:inc_c1(P1).
2
10> counter:inc_c1(P1).
3
11> counter:value_c1(P1).
3
12> counter:inc_c1(P1).  
4
13> counter:inc_c1(P1).
done
14> counter:value_c1(P1).
done
15> counter:inc_c1(P1).  
done
16> counter:stop_c1(P1).
stop
17> counter:inc_c1(P1). 
{error,no_response}
18> 
1>c(../src/counter”)。
{好的,计数器}
2> {Ref,P}=counter:start_after(5000,io,format,[“到此结束!”])。
{#Ref,}
结束了!3> 
3> {Refa,Pa}=counter:start_after(50000,io,format,[“到此结束!”])。
{#Ref,}
4> 爸爸!{取消,重构}。
{取消,#参考}
5> 刷新()。
Shell得到{u接收后,#Ref,done}
Shell得到{在#接收#Ref,取消}
好啊
6> P1=计数器:启动_c1(5)。
7> 柜台:inc_c1(P1)。
1.
8> 柜台:inc_c1(P)。
{错误,没有响应}
9> 柜台:inc_c1(P1)。
2.
10> 柜台:inc_c1(P1)。
3.
11> 计数器:值_c1(P1)。
3.
12> 柜台:inc_c1(P1)。
4.
13> 柜台:inc_c1(P1)。
完成
14> 计数器:值_c1(P1)。
完成
15> 柜台:inc_c1(P1)。
完成
16> 计数器:停止c1(P1)。
停止
17> 柜台:inc_c1(P1)。
{错误,没有响应}
18> 

C+=1的含义是修改C的值。它在Erlang中是无意义的,因为它只能给出以下结果:

1> C = C+1.
* 1: variable 'C' is unbound
C = 1.
1
3> C = C+1.
** exception error: no match of right hand side value 2
请记住,“A=B”并不意味着将B的值分配给A,而是将A与B进行“模式匹配”

  • 如果A未绑定,则它将绑定到A,值为B
  • 如果A=:=B未执行任何操作,则进程将继续
  • 如果A=/=B,则进程崩溃
所以,是的,若你们想要一个计数器,或者任何改变的信息,你们必须使用一个状态变量,作为递归循环的参数传递。从这个角度来看,您的上一个代码是正确的,但是让我们看看在shell中调用“call()”时会发生什么

首先,它在同一个进程中(shell)调用函数while_loop(10,0)

10不等于0,因此它在_循环(10,1)时立即调用

10不等于1,因此它在_循环(10,2)时立即调用

依此类推,直到它调用while_循环(10,10)。现在10=:=10是真的,并且这个结果与案例中的任何子句都不匹配,因此您会得到一个错误,进程会崩溃

由于您的代码不包含任何消息接收,只需循环一个循环直到崩溃,因此wole过程只需几微秒,因此看起来它会立即失败

根据您的期望,您可以想象几种类型的计数器,以下是两个示例:

-module(counter).

-compile(export_all).

% one counter that help you to count some events

% interface

start_c1(End) when is_integer(End) ->
    spawn(?MODULE,counter1,[End]).

start_link_c1(End) when is_integer(End) ->
    spawn_link(?MODULE,counter1,[End]).

inc_c1(Pid) when is_pid(Pid) ->
    Ref = make_ref(),
    Pid ! {inc,self(),Ref},
    receive
        {Ref,done} -> done;
        {Ref,V} -> V
    after 1000 ->
        {error,no_response}
    end.

value_c1(Pid) when is_pid(Pid)  ->
    Ref = make_ref(),
    Pid ! {get_value,self(),Ref},
    receive
        {Ref,V} -> V
    after 1000 ->
        {error,no_response}
    end.

stop_c1(Pid)  when is_pid(Pid) ->
    Pid ! stop.

% the counter

counter1(End) -> counter1_loop(End,0).

counter1_loop(End,V) ->
    receive
        {inc,Pid,Ref} when V =/= done -> 
            NewV = case V+1 of
                End -> done;
                Nv -> Nv
            end,
            Pid ! {Ref,NewV},
            counter1_loop(End,NewV);
        {inc,Pid,Ref} ->
            Pid ! {Ref,done},
            counter1_loop(End,done);         
        {get_value,Pid,Ref} ->
            Pid ! {Ref,V},
            counter1_loop(End,V);
        stop ->
            ok
    end.

% One kind of timeout that execute something after a while - 
% note it exists a similar one in the library

start_after(T,M,F,A) when is_integer(T), is_list(A) ->
    Ref = make_ref(),
    {Ref,spawn(?MODULE,after_receive,[T,M,F,A,self(),Ref])}.

cancel_after(P) when is_pid(P) ->
    P ! cancel.


% the counter
after_receive(T,M,F,A,Pid,Ref) ->
    receive
        {cancel,Ref} -> Pid ! {after_receive,Ref,cancelled}
    after T ->
        Pid ! {after_receive,Ref,done},
        apply(M,F,A)
    end.
下面是如何使用它们:

1> c("../src/counter").
{ok,counter}
2> {Ref,P} = counter:start_after(5000,io,format,["This is the end!" ]).
{#Ref<0.0.0.29>,<0.33.0>}
This is the end!3> 
3> {Refa,Pa} = counter:start_after(50000,io,format,["This is the end!" ]).
{#Ref<0.0.0.34>,<0.35.0>}
4> Pa ! {cancel,Refa}.
{cancel,#Ref<0.0.0.34>}
5> flush().
Shell got {after_receive,#Ref<0.0.0.29>,done}
Shell got {after_receive,#Ref<0.0.0.34>,cancelled}
ok
6> P1 = counter:start_c1(5).
<0.52.0>
7> counter:inc_c1(P1).
1
8> counter:inc_c1(P). 
{error,no_response}
9> counter:inc_c1(P1).
2
10> counter:inc_c1(P1).
3
11> counter:value_c1(P1).
3
12> counter:inc_c1(P1).  
4
13> counter:inc_c1(P1).
done
14> counter:value_c1(P1).
done
15> counter:inc_c1(P1).  
done
16> counter:stop_c1(P1).
stop
17> counter:inc_c1(P1). 
{error,no_response}
18> 
1>c(../src/counter”)。
{好的,计数器}
2> {Ref,P}=counter:start_after(5000,io,format,[“到此结束!”])。
{#Ref,}
结束了!3> 
3> {Refa,Pa}=counter:start_after(50000,io,format,[“到此结束!”])。
{#Ref,}
4> 爸爸!{取消,重构}。
{取消,#参考}
5> 刷新()。
Shell得到{u接收后,#Ref,done}
Shell得到{在#接收#Ref,取消}
好啊
6> P1=计数器:启动_c1(5)。
7> 柜台:inc_c1(P1)。
1.
8> 柜台:inc_c1(P)。
{错误,没有响应}
9> 柜台:inc_c1(P1)。
2.
10> 柜台:inc_c1(P1)。
3.
11> 计数器:值_c1(P1)。
3.
12> 柜台:inc_c1(P1)。
4.
13> 柜台:inc_c1(P1)。
完成
14> 计数器:值_c1(P1)。
完成
15> 柜台:inc_c1(P1)。
完成
16> 计数器:停止c1(P1)。
停止
17> 柜台:inc_c1(P1)。
{错误,没有响应}
18> 

Var=:=Counter
时,您编辑的版本没有子句,因此崩溃。最好在函数子句中使用模式匹配

-module(whileloop).
-export([call/0, while_loop/2]).

call() ->
    while_loop(10,0).

while_loop(Var, Var) ->
    ok;
while_loop(Var, Counter) -> 
    while_loop(Var, Counter + 1).
当然,你需要在循环中做一些事情。您可以使用lambdas进行以下操作:

-module(whileloop).
-export([call/0, while_loop/2]).

call() ->
    while_loop(10, 0, fun(Counter) -> io:format("Counter: ~p~n", [Counter]) end).

while_loop(Var, Var, _) ->
    ok;
while_loop(Var, Counter, Fun) ->
    Fun(Counter),
    while_loop(Var, Counter + 1).

Var=:=Counter
时,您编辑的版本没有子句,因此崩溃。最好在函数子句中使用模式匹配

-module(whileloop).
-export([call/0, while_loop/2]).

call() ->
    while_loop(10,0).

while_loop(Var, Var) ->
    ok;
while_loop(Var, Counter) -> 
    while_loop(Var, Counter + 1).
当然,你需要在循环中做一些事情。您可以使用lambdas进行以下操作:

-module(whileloop).
-export([call/0, while_loop/2]).

call() ->
    while_loop(10, 0, fun(Counter) -> io:format("Counter: ~p~n", [Counter]) end).

while_loop(Var, Var, _) ->
    ok;
while_loop(Var, Counter, Fun) ->
    Fun(Counter),
    while_loop(Var, Counter + 1).

好的,但是如果我需要在其他地方知道,
counter++
的等价性呢。我在上面的代码中尝试了
while_loop(Var,counter+1)
,这是非法模式吗?我删除了行
Counter+=1,
@lost\u,使用\u编码,Erlang中没有一行。您不能像在Erlang中那样更改变量的值。阅读本文了解更多信息:您确实保留了分号
在它之后?然后删除
计数器+=1
行?好的,但是如果我需要在其他地方知道这一点,那么
计数器+++
的等价性如何呢?我在上面的代码中尝试了
while_loop(Var,Counter+1)
,这是非法模式吗?我删除了行
计数器+=1<