[英]Why does erlang:foo() compile?
為什么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
為什么編譯器在編譯期間沒有發出錯誤或警告? 它應該知道導出的功能,不應該嗎?
Erlang是一種動態語言。 然而,在編譯后進行類型檢查和靜態分析是一種很好的做法。
Dialyzer工具用於檢查此類錯誤情況。
編譯器在編譯時不知道它的原因是因為可以在運行時(以及從遠程節點)從代碼路徑中搜索和動態加載函數。 透析器將在運行時根據代碼路徑檢查代碼。
從遠程節點加載代碼的能力意味着可以在設備上安裝基本的“系統”,然后設備可以從網絡引導自身。
你應該還記得二郎,你可以生成函數調用的另一個特點在飛行中使用結構,如:
erlang:apply(ModuleName, FunctionName, ArgList)
所以在這種情況下,根本不可能知道函數是否在編譯時存在。
雖然模塊和函數現在可能在編譯時存在,但您可以熱插拔模塊並卸載代碼,因此在運行時可能不存在。
您可以使用xref
應用程序來檢查已棄用,未定義和未使用的函數的使用情況(以及更多!)。
使用debug_info
編譯模塊:
Eshell V6.2 (abort with ^G)
1> c(test, debug_info).
{ok,test}
使用xref:m/1
檢查模塊:
2> xref:m(test).
[{deprecated,[]},
{undefined,[{{test,start,0},{erlang,foo,0}}]},
{unused,[]}]
您可以在此處查看有關xref
更多信息:
我認為這是一個實現問題,因為Erlang開發人員決定運行時鏈接而不是構建時鏈接。 部分原因可能是版本控制和/或動態代碼加載。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.