以下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.
答案 0 :(得分:3)
首先简短回答,使用Dialyzer的格言:
Maxim编号2是(当然不是很令人满意)"标准"回答任何"为什么Dialyzer没有发现这个错误"问题
更多解释性答案:
Dialyzer对函数返回值的分析经常进行过度近似。因此,类型中包含的任何值都被视为"可能返回"值。这有一个令人遗憾的副作用,有时候肯定会返回的值(例如你的output
原子)也被认为是#34;可能会返回"。透析器必须保证格言1(永远不会出错),因此在可能返回意外值的情况下#34;它不会发出警告(在error
的规范中),除非不能返回任何实际指定的值。最后一部分在整个函数的级别进行检查,因为在您的示例中,某些子句确实返回foo
,因此不会生成警告。
最后,如果您希望Dialyzer对规格非常严格,您可以使用ok
或-Wunderspecs
或-Woverspecs
(请参阅有关每项规定的文档)