我对Erlang功能有疑问。请参阅Erlang shell中的代码:
1> F1 = fun() -> timer:sleep(1000) end. #Fun<erl_eval.20.111823515> 2> F2 = fun() -> io:format("hello world~n", []) end. #Fun<erl_eval.20.111823515>
F1 和 F2 不同,但为什么他们都有标识符#Fun<erl_eval.20.111823515>
?这些神奇的数字意味着什么?
ERTS Manual中有一段说:
When interpreting the data for a process, it is helpful to know that anonymous
function objects (funs) are given a name constructed from the name of the
function in which they are created, and a number (starting with 0) indicating
the number of that fun within that function.
我也无法理解本段的含义,请您解释一下吗?
答案 0 :(得分:6)
不要在匿名函数的名称中读出太多含义。所有你可以安全地摆脱它的是创建它们的模块的名称。您可以尝试对模块中的乐趣进行计数以找到哪一个,但我不会打扰。
话虽如此,但两个乐趣都有同名的原因。在shell中输入的表达式不会被编译,而是由模块erl_eval
中的解释器进行评估。这个模块有一个乐趣来解释每个arity的乐趣。因此,erl_eval
对于arity 1,#Fun<erl_eval.20.111823515>
的乐趣有一个乐趣。 Hacky,但它确实有效。
答案 1 :(得分:2)
考虑模块中的相同功能(现在不要想到shell)
-module(fun_test).
-export([test/0]).
test() ->
F1 = fun() -> timer:sleep(1000) end,
F2 = fun() -> io:format("hello world~n", []) end,
{F1,F2}.
输出如下
1> fun_test:test().
{#Fun<fun_test.0.78536365>,#Fun<fun_test.1.78536365>}
在上面的例子中,匿名函数对象F1和F2名称是使用模块fun_test的名称,唯一标识符0和1(模块中每个函数的增量),返回地址等构造的,如{{ 3}}。这解释了手册中提到的段落。虽然不是很有用,但函数编号在调试过程中很方便,因为跟踪中的-test/0-fun-1-
会告诉您test / 0函数中的匿名函数1是错误的来源。
对于shell中定义的函数,使用erv_eval模块,如rvirding所述。函数对象声明的结果是返回该arity的erl_eval。所以总是为该arity返回相同的值。