Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang 使用typer注释后透析机的运行未显示任何警告_Erlang_Typechecking_Dialyzer - Fatal编程技术网

Erlang 使用typer注释后透析机的运行未显示任何警告

Erlang 使用typer注释后透析机的运行未显示任何警告,erlang,typechecking,dialyzer,Erlang,Typechecking,Dialyzer,在一个有大约6000行Erlang代码但没有类型-spec()注释的项目中,我尝试了以下方法: typer --annotate *.erl 我将所有*.erl文件替换为带注释的文件,然后运行 dialyzer --src -c *.erl 我本以为会收到很多警告(第一次运行了透析器/打字机组合),但完成后,透析器报告的所有内容都是用户默认的2个旧调用,同时不存在函数 没有触发其他默认警告 我使用它时犯了错误,还是这样的结果很常见 自动注释与打字机和透析器的组合是否没有那么有用,或者我只是运

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

typer --annotate *.erl
我将所有
*.erl
文件替换为带注释的文件,然后运行

dialyzer --src -c *.erl
我本以为会收到很多警告(第一次运行了透析器/打字机组合),但完成后,透析器报告的所有内容都是用户默认的2个旧调用,同时不存在函数

没有触发其他默认警告

我使用它时犯了错误,还是这样的结果很常见

自动注释与
打字机
透析器
的组合是否没有那么有用,或者我只是运气好,代码没有问题


旁注:我不得不注释掉3或4个
-spec()
s,因为
透析器


我正在使用来自Erlang R13B04的透析器v2.2.0和打字机版本v0.1.7.4,作为在Erlang bugs列表中报告错误的副作用。我从透析器和打字机的发明者Kostis Sagonas那里得到了详细的答案

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

佩尔·斯特里辛格写道:

顺便说一句:仅仅做--annotate时不收到任何警告是正常的吗 在打字机和透析器中,无需手动调整规格

对。事实上,打字机只是透析器基本类型推断的前端(即没有警告标识组件)

依我看,如果你不打算手动“按摩”你得到的规格,并为其中一些规格提供更多信息,那么这样做就没有什么意义。看看你以前的计划。如果您引入的类型如中所示,则可以更好地表示这两种类型指的是相同数量的事实:

  -type packet() :: <<_:64,_:_*8>>,
然后规格就已经看起来更好了。另外,透析器/打字机没有关于您打算在function
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返回的任何类型。您可能知道这个类型是什么,所以还应该为它引入一个类型并使用它的专有名称

希望这有帮助

科斯蒂斯

另外,很遗憾你在erlang bug中发布了这篇文章,因为上面包含的信息比实际的bug更有趣

因为他引用了一个代码片段,所以我把它包括在我的bug报告中,我把它包括在这里。以下代码片段由
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}.
-记录(can_pkt,{id,data,timestamp})。
-规格录制(,乐趣)->
any()),atom()| pid()|{atom(),})->any()。
recv(小包,recv_fun,Chan)->
P=解码(数据包),
#can_pkt{id=can_id,data=can_data}=P,
记录乐趣(P)。
-规范解码()->
#can_pkt{id::,data::binary(),timestamp::char()}。
解码()->
#can_pkt{id=id,data=data,timestamp=timestamp}。
-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}.