带-spec类型签名的Erlang程序为何可编译?如何捕获类型错误?
问题解答
为什么Erlang可以正常编译该程序
Erlang是动态类型语言,默认的官方编译器erlc不会对-spec类型标注做编译期强制校验,-spec默认仅用作文档标注和静态分析工具的输入依据。
你当前这段代码只有在实际运行调用add2/1的时候才会触发运行时类型错误badarg,编译阶段仅会校验语法合法性、导出函数是否存在等基础规则,不会做类型校验,因此可以正常编译通过。
如何在Erlang中捕获这类类型错误
你可以使用Erlang官方提供的静态类型分析工具Dialyzer来捕获这类类型不匹配问题,操作步骤如下:
- 编译代码时添加
debug_info参数,生成携带类型分析所需元信息的beam文件:erlc +debug_info a.erl - 运行Dialyzer对生成的beam文件做静态分析:
dialyzer a.beam
运行后Dialyzer会明确输出add/2的第二个参数类型不符合integer()要求的错误提示,成功在运行前捕获该问题。
Elixir编写相同逻辑能否捕获这类错误
Elixir同样是动态类型语言,原生编译器默认也不会对@spec类型注解做编译期强制校验,直接编译相同逻辑的代码也不会报错。
但Elixir生态可以通过引入dialyxir(Dialyzer的Elixir封装工具)做静态类型分析,和Erlang一样可以在静态分析阶段捕获该类类型不匹配错误。如果需要更强的编译期类型检查,也可以引入第三方静态类型扩展工具实现。
内容的提问来源于stack exchange,提问作者wang kai
相关产品推荐
相关产品推荐

