Dialyzer错过了类型规范的错误

时间:2018-03-04 02:26:53

标签: erlang dialyzer

以下Erlang代码似乎在其类型规范中有明显错误,但dialyzer表示一切正常。我误解了还是透析器中的一个错误?在Erlang 19.3上运行

-module(foobar).

-export([foo/1]).

-spec foo(atom()) -> ok | {error, atom()}.
foo(Arg) -> bar(Arg).

-spec bar(atom()) -> ok | error.
bar(baz) -> error;
bar(_) -> ok.

1 个答案:

答案 0 :(得分:3)

首先简短回答,使用Dialyzer的格言:

  1. 透析器永远不会出错。(经常被Erlang程序员朗诵)
  2. Dialyzer从未承诺会在您的代码中发现所有错误。(不那么有名)
  3. Maxim编号2是(当然不是很令人满意)"标准"回答任何"为什么Dialyzer没有发现这个错误"问题

    更多解释性答案:

    Dialyzer对函数返回值的分析经常进行过度近似。因此,类型中包含的任何值都被视为"可能返回"值。这有一个令人遗憾的副作用,有时候肯定会返回的值(例如你的output原子)也被认为是#34;可能会返回"。透析器必须保证格言1(永远不会出错),因此在可能返回意外值的情况下#34;它不会发出警告(在error的规范中),除非不能返回任何实际指定的值。最后一部分在整个函数的级别进行检查,因为在您的示例中,某些子句确实返回foo,因此不会生成警告。

    最后,如果您希望Dialyzer对规格非常严格,您可以使用ok-Wunderspecs-Woverspecs(请参阅有关每项规定的文档)