为什么 erlang:foo() 可以编译?
为什么 Erlang 编译器在编译时不检测未定义的函数。
如果我写 test.erl:
-module(test).
-export([start/0]).
start() ->
erlang:foo().
它编译得很好。
Eshell V5.6.5 (abort with ^G)
1> c(test).
{ok,test}
2>
但运行时会崩溃。
2> test:start().
** exception error: undefined function erlang:foo/0
为什么编译器在编译过程中不发出错误或警告? 它应该知道导出函数,不是吗?
Why doesn't the Erlang compiler detect undefined functions in compile time.
If I write test.erl:
-module(test).
-export([start/0]).
start() ->
erlang:foo().
It compiles fine.
Eshell V5.6.5 (abort with ^G)
1> c(test).
{ok,test}
2>
But crashes runtime.
2> test:start().
** exception error: undefined function erlang:foo/0
Why doesn't the compiler issue an error or a warning about this during compilation? It should know about exported functions, shouldn't it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Erlang 是一种动态语言。 然而,在编译后进行类型检查和静态分析是一种很好的做法。
Dialyzer 工具用于检查此类错误情况。
编译器在编译时不知道它的原因是因为可以在运行时从代码路径(也可以从远程节点)搜索并动态加载函数。 Dialyzer 将在运行时根据代码路径检查代码。
从远程节点加载代码的能力意味着可以在设备上安装基本“系统”,然后设备可以从网络引导自身。
您还应该记住 Erlang 的另一个特性,即您可以使用构造动态生成函数调用就像:
所以在这种情况下,根本不可能知道该函数在编译时是否存在。
尽管模块和函数现在可能在编译时存在,但您可以热交换模块并卸载代码,因此它在运行时可能不存在。
Erlang is a dynamic language. It is good practice however to do type checking and static analysis post-compilation.
The tool Dialyzer is used to check for this sort of error condition.
The reason the compiler doesn't know about it at compile time is because functions can be searched for and dynamically loaded from the code path at run time (and also from a remote node). The Dialyzer will check the code against the code path at the time it is run.
The ability to load code from a remote node means that basic 'systems' can be installed on a device and the device can then bootstrap itself from the network.
You should also remember another characteristic of Erlang that you can generate function calls on the fly using constructs like:
so in that case it is simply not possible to know if the function exists at compile time or not.
And although the module and function might exist now at compile time, you can hot swap modules out and unload code, so it may not be there at run time.
我认为这是一个实现问题,因为 Erlang 开发人员决定运行时链接而不是构建时链接。 部分原因可能与版本控制和/或动态代码加载有关。
I think that this is an implementation question as the Erlang developers decided to to runtime linking rather than build-time linking. Part of the reason may have something to do versioning and/or dynamic code loading.
您可以使用
xref
应用程序来检查已弃用、未定义和未使用的函数(以及更多!)的使用情况。使用
debug_info
编译模块:使用
xref:m/1
检查模块:您可能想在此处查看有关
xref
的更多信息:Erlang -- 外部参照 - 交叉引用工具(工具用户指南)
Erlang -- xref(工具参考手册)
You may use the
xref
application to check the usage of deprecated, undefined and unused functions (and more!).Compile the module with
debug_info
:Check the module with
xref:m/1
:You may want to check out more about
xref
here:Erlang -- Xref - The Cross Reference Tool (Tools User's Guide)
Erlang -- xref (Tools Reference Manual)