在elixir中定义匿名函数后显示的数字是多少?

时间:2015-06-16 00:56:39

标签: elixir

在elixir中定义匿名函数时,会得到这样的结果。

#Function<6.90072148/1 in :erl_eval.expr/5>

我注意到的是这个数字是基于函数的arity。所以1 arg函数总是

#Function<6.90072148/1 in :erl_eval.expr/5>

两个arg函数始终是

#Function<12.90072148/2 in :erl_eval.expr/5>

三个arg函数总是

#Function<18.90072148/3 in :erl_eval.expr/5>

返回的号码是多少,以及如何派生?

1 个答案:

答案 0 :(得分:14)

该数字由索引和函数的唯一名称组成,这些名称由编译器生成。看看implementation of the inspect protocol for functions。它包含这段话:

"#Function<#{uniq(fun_info)}/#{fun_info[:arity]} in " <>
  "#{Inspect.Atom.inspect(mod)}#{extract_name(fun_info[:name])}>"

其中fun_info是指先前调用:erlang.fun_info的结果。这松散地转换为以下伪代码,其中所有内插值都引用fun_info的元素:

"#Function<#{new_index}.#{uniq}/#{arity} in #{module}.#{name}>"

正如您所正确观察到的那样,/之后的部分表示了arity。 modulename显示功能的定义位置。 new_index是指向模块函数表的指针,uniq是编译器生成的模块的哈希值。当您为函数调用:erlang.fun_info时,您将能够识别inspect字符串中的值:

iex> fun = fn x -> x end
#Function<6.90072148/1 in :erl_eval.expr/5>

iex> fun_info = :erlang.fun_info(fun)
[pid: #PID<0.58.0>,
 module: :erl_eval,
 new_index: 6,
 new_uniq: <<171, 204, ...>>,
 index: 6,
 uniq: 90072148,
 name: :"-expr/5-fun-4-",
 arity: 1,
 env: [...]]

uniq值和索引一起提供了一种唯一标识匿名函数的方法。请注意,在iex内,对于您创建的所有函数,这些所谓的唯一值将非常相似,但是当代码正确且#34;编译后,它们将是独一无二的。考虑以下iex会话:

iex> fn -> end
#Function<20.90072148/0 in :erl_eval.expr/5>
iex> fn -> end
#Function<20.90072148/0 in :erl_eval.expr/5>
iex> fn -> end
#Function<20.90072148/0 in :erl_eval.expr/5>

现在将其与使用elixir fun.exs运行以下文件进行比较:

IO.inspect fn -> end
IO.inspect fn -> end
IO.inspect fn -> end

# this prints

#Function<0.120576197 in file:fun.exs>
#Function<1.120576197 in file:fun.exs>
#Function<2.120576197 in file:fun.exs>