3

我有一个关于 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>

F1F2不同,但为什么它们都有标识符#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.

我也无法理解这一段的意思,你能解释一下吗?

4

2 回答 2

6

不要在匿名函数的名称中解读太多含义。您可以安全地从中得到的只是创建它们的模块的名称。您可以尝试计算模块中的乐趣来找到哪个,但我不会打扰。

话虽如此,这两个乐趣的名称相同是有原因的。在 shell 中输入的表达式不会被编译,而是由模块中的解释器评估erl_eval。这个模块有一个有趣的解释每个arity的乐趣。所以有一个有趣erl_eval的arity 1 #Fun<erl_eval.20.111823515>,。哈克,但它的工作原理。

于 2013-05-18T17:47:19.170 回答
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(模块中每个函数的增量)、返回地址等构造的,如ERTS 手册中所定义。这解释了手册中提到的段落。虽然不是很有用,但函数编号在调试期间很方便,因为-test/0-fun-1-跟踪中会告诉您 test/0 函数中的匿名函数 1 是错误的来源。

对于 shell 中定义的函数,请使用 rvirding 解释的 erl_eval 模块。函数对象声明的结果是该参数的 erl_eval 的返回。所以总是为那个arity返回相同的值。

于 2013-05-19T19:24:43.470 回答