erlang - 使用打字机注释后运行透析器未显示任何警告

标签 erlang typechecking dialyzer

在一个包含大约 6000 行 Erlang 代码但没有类型 -spec() 注释的项目中,我尝试了以下操作:

typer --annotate *.erl

我用带注释的文件替换了所有 *.erl 文件并运行

dialyzer --src -c *.erl

我预计会收到很多警告(第一次运行透析器/打字机组合),但在完成其操作后,所有透析器报告的都是 user_default 中的 2 个旧调用,同时调用不存在的函数。

没有触发其他默认警告。

我使用它时是否犯了错误,或者这样的结果很常见吗?

自动注释与 typerdialyzer 的组合不是很有用,还是我只是幸运,我的代码没有问题?


旁注:我必须注释掉 3 或 4 个 -spec(),因为 dialyzer crashed on them .

我使用的是 Erlang R13B04 的 Dialyzer v2.2.0 和 TypEr 版本 v0.1.7.4

最佳答案

作为在 erlang-bugs 列表上报告错误的副作用,我从透析器和打字机的发明者 Kostis Sagonas 那里得到了详细的答案。

对于我的附带问题,我得到了以下精彩而详细的答案:

On Sun, May 1, 2011 at 5:53 PM, Kostis Sagonas wrote:

Peer Stritzinger wrote:

BTW: is it normal not to get any warnings when just doing --annotate in typer and then dialyzer with no manually tweaked spec's

是的。事实上,typer只是dialyzer基本类型推断的前端(即没有警告识别组件)。

IMO,如果您不打算手动“按摩”您获得的规范并为其中一些规范提供更多信息,那么这样做就没有什么意义。看看你以前的程序。如果您引入如下类型,则可以更好地表达两个 <<:64,:_*8>> 类型引用相同数量的事实:

  -type packet() :: <<_:64,_:_*8>>,

channel 类似:

  -type channel() :: atom() | pid() |{atom(),_}.

然后规范就已经看起来更好了。另外,dialyzer/typer 没有关于您打算在函数 recv/3 的第二个参数中使用哪种类型的乐趣的信息。但你做了!从代码中可以清楚地看出,它需要 #can_pkt{}记录,那么为什么不向其字段添加适当的类型并为其引入类型呢?

  -record(can_pkt, {id :: id(), data :: binary(), timestamp :: ts()}).
  -type can_pkt() :: #can_pkt{}.

那么规范看起来会好得多:

  -spec recv(packet(), fun((can_pkt()) -> R), channel()) -> R.
  -spec decode(packet()) -> can_pkt().

请注意,我使用了占位符类型变量 R表示函数 recv/2返回第二个参数中 fun 返回的任何类型。您可能知道这个类型是什么,因此您还应该为其引入一个类型并使用其正确的名称。

希望这有帮助,

科斯蒂斯

PS。遗憾的是您将其发布在 erlang-bugs 中,因为在我看来,上面包含的信息比实际的错误更有趣。

由于他引用了我的错误报告中包含的代码片段,因此我将其包含在这里。以下代码片段被自动注释为 typer --annotate :

-record(can_pkt, {id, data, timestamp}).

-spec recv(<<_:64,_:_*8>>,fun((_) -> 
      any()),atom() | pid() | {atom(),_}) -> any().

recv(Packet, Recv_fun, Chan) ->
    P = decode(Packet),
    #can_pkt{id=Can_id, data=Can_data}=P,
    Recv_fun(P).

-spec decode(<<_:64,_:_*8>>) -> 
      #can_pkt{id::<<_:11>>,data::binary(),timestamp::char()}.

decode(<<_:12, Len:4, Timestamp:16,
        0:3, Id:11/bitstring, 0:18,
        Data:Len/binary, _/binary>>) ->
    #can_pkt{id=Id, data=Data, timestamp=Timestamp}.

关于erlang - 使用打字机注释后运行透析器未显示任何警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5849335/

相关文章:

typescript - 错误的功能分配

Python 3.5类型注释变量无初始值

erlang - 在 Erlang 梁上使用 Dialyzer 和源代码之间有效率差异吗?

erlang - Erlang VM 使用了多少内存?

mysql - 如何在 Erlang 中安装驱动程序? (特别是 MySQL-otp 驱动程序)

cython - mypy 不喜欢别名 Cython 类型

protocols - 如何避免协议(protocol)的透析器错误?

erlang - 转换到 `any()` 是让 Dialyzer 接受 ETS 匹配模式的好解决方案吗?

crash - 控制rabbitmq 'name'而不是 'sname'

erlang - 芝加哥老板的错误 "init terminating in do_boot"