关于Erlang函数,尤其是函数的标识符

时间:2013-05-18 16:11:23

标签: erlang

我对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.

我也无法理解本段的含义,请您解释一下吗?

2 个答案:

答案 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返回相同的值。