我正在尝试做这样的事情:
test(Tester) ->
case Tester of
start -> X = 4
ok -> X = X + 5,
Y = X/5;
terminate -> Y
end.
但这不完全是。我知道可以通过tail或简单递归来实现。 通常X和Y是不受约束的。
在不使用erlang全局变量的情况下,是否可以在这些情况之间进行通信?
答案 0 :(得分:5)
Erlang是一种功能语言,这意味着我们不会在代码的不同部分之间进行通信,也不会在没有目的的情况下将值存储在变量中,我们只是计算返回值(有时会产生一些副作用)。如果我们在不同的代码分支中进行通用计算,则可以将其放在通用函数中。
test(Tester) ->
case Tester of
start -> 4;
ok -> computeY();
terminate -> computeY()
end.
computeY() ->
X = 4 + 5,
X/5.
答案 1 :(得分:4)
如果您需要在case
语句的任何子句主体中访问变量,则必须在case
语句之前分配它,或者有时您可以在{ {1}}子句模式:
test(Arg) ->
Size = get_size(Arg), % I will use 'Size' in each clause body
case Arg of
#{foo := Foo} -> % if Arg is an Erlang map and has key 'foo'
% I can use 'Foo' only here:
io:format("It's a map with size ~p and has key foo with value ~p\n", [Size, Foo]);
[Baz|_] -> % if Arg is an Erlang list with at least one element
% I can use 'Baz' only here and for example i can NOT use 'Foo' here:
io:format("It's a list with size ~p and its first element is ~p\n", [Size, Baz]);
_ ->
io:format("Unwanted argument ~p with ~p size\n", [Arg, Size])
end.
get_size(X) when is_map(X) -> map_size(X);
get_size(X) when is_list(X) -> length(X);
get_size(_) -> unknown.
我将上面的代码放在名为fun
的Erlang Test
中,以便在外壳中使用它而无需编译模块文件:
1> Test([5,4,3,2,1]).
It's a list with size 5 and its first element is 5
ok
2> Test(#{key => value, foo => ':)'}).
It's a map with size 2 and has key foo with value ':)'
ok
3> Test([]).
Unwanted argument [] with 0 size
ok
4> Test(#{key => value}).
Unwanted argument #{key => value} with 1 size
ok
5> Test(13).
Unwanted argument 13 with unknown size
ok
如果您对变量绑定感到好奇,建议阅读this article
答案 2 :(得分:0)
要在Erlang中执行此操作,您将启动(产生)一个将X保留在内存中的进程以及应该响应的进程的PID(进程ID),除非您希望每次都传递一个不同的PID时间以及开始/确定/终止。 Erlang中的进程具有自己的内存,状态或loopData。生成一个知道如何处理特定消息的进程后,您将其传递给消息并通过将消息发回来进行回复。
start_test() ->
TestPID = spawn(?MODULE, test, [self()]),
TestPID ! start,
receive
X -> io:format("X is: ~p~n",[X]
end,
TestPID ! ok,
receive
{X,Y} -> io:format("X is: ~p, Y is: ~p~n",[X, Y]
end,
TestPID ! terminate,
receive
Y -> io:format("Y is: ~p~n",[Y]
end.
test(PID) ->
receive
start -> PID ! 4,
test(4, undefined, PID);
terminate -> undefined
end.
test(X, Y, PID) ->
receive
ok -> PID ! {X+5, (X+5)/5},
test(X+5, (X+5)/5, PID);
terminate -> PID ! Y
end.
别忘了创建模块并导出start_test / 0和test / 1
如果运行start_test(),则应获得输出
X is: 4
X is: 9, Y is: 1.8
Y is: 1.8