为什么这个带有类型签名的Erlang prog可以编译?

lo8azlld  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(168)

我有这样的计划:

-module(a).
-export([add/2]).
-export([add2/1]).

-spec add(integer(),integer())->integer().
add(A,B)->A+B.

add2(C)->C+add(1,"a").

我可以编译这个程序没有错误。但我想我应该得到错误的行

add(1,"a").

在任何静态类型语言中,它都不能编译,那么为什么Erlang要编译它呢?如何
写类型签名,这样Erlang就能捕捉到这个错误?如果Erlang不能,Elixir能写同样的程序但能捕捉到这个错误吗?谢谢!

raogr8fs

raogr8fs1#

Erlang不是静态类型的语言,它总是动态类型的。你不能在编译过程中捕获它,因为erlc根本不关心-spec。它只用于文档和Dialyzer(技术上是外部工具)可以用它来做一些(有限的)合同的静态分析。
有关如何使用透析器,请查看:

inkz8wg9

inkz8wg92#

Erlang编译器不检查类型规范。你可以使用Erlang中包含的Dialyzer来检查它们:

dialyzer --src a.erl

它提供以下输出:

Proceeding with analysis...
a.erl:8: Function add2/1 has no local return
a.erl:8: The call a:add
         (1,
          "a") will never return since the success typing is 
         (number(),
          number()) -> 
          number() and the contract is 
          (integer(), integer()) -> integer()
 done in 0m0.19s
done (warnings were emitted)

第一次运行透析器时,它会抱怨没有标准应用程序的PLT(持久查找表)。您可以使用以下方法构建透析器:

dialyzer --build_plt --apps erts kernel stdlib mnesia

相关问题