在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>
返回的数字是多少,它是如何派生的?
Pat*_*ity 14
该数字由索引和函数的唯一名称组成,这些名称由编译器生成.看一下功能检查协议的实现.它包含这段经文:
"#Function<#{uniq(fun_info)}/#{fun_info[:arity]} in " <>
"#{Inspect.Atom.inspect(mod)}#{extract_name(fun_info[:name])}>"
Run Code Online (Sandbox Code Playgroud)
where fun_info指的是之前调用的结果:erlang.fun_info.这松散地转换为以下伪代码,其中所有内插值都引用以下元素fun_info:
"#Function<#{new_index}.#{uniq}/#{arity} in #{module}.#{name}>"
Run Code Online (Sandbox Code Playgroud)
正如你已经正确观察到的那样,后面的部分/表示了arity.module并name显示功能定义的位置.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: [...]]
Run Code Online (Sandbox Code Playgroud)
uniq值和索引一起提供了一种唯一标识匿名函数的方法.请注意,iex对于您创建的所有函数,这些所谓的唯一值内部将非常相似,但是当代码"正确"编译时,它们将是唯一的.考虑以下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>
Run Code Online (Sandbox Code Playgroud)
现在将其与运行以下文件进行比较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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |