如何让 Dialyzer 接受对有意抛出的函数的调用?

时间:2021-01-15 12:08:58

标签: erlang dialyzer

我有一个函数,当它的第一个参数是原子 throw 时故意抛出。

此代码的简化版本是:

-module(sample).

-export([main/1, throw_or_ok/1]).

main(_Args) ->
    throw_or_ok(throw).


throw_or_ok(Action) ->
    case Action of
        throw -> throw("throwing");
        ok -> ok
    end.

调用 throw_or_ok 时出现透析器错误:

sample.erl:7: The call sample:throw_or_ok
         ('throw') will never return since it differs in the 1st argument from the success typing arguments:
         ('ok')

添加规范没有帮助,错误信息是一样的:

-module(sample).

-export([main/1, throw_or_ok/1]).

-spec main(_) -> no_return().
main(_Args) ->
    throw_or_ok(throw).

-spec throw_or_ok(throw) -> no_return(); (ok) -> ok.
throw_or_ok(Action) ->
    case Action of
        throw -> throw("throwing");
        ok -> ok
    end.

我怎样才能让 Dialyzer 接受对 throw_or_ok/1 的保证会抛出的调用?

2 个答案:

答案 0 :(得分:0)

不幸的是,目前没有干净的方法可以通过规格将其标记为 Dialyzer 可接受。

不过,也许您可​​以使用忽略警告注释。

答案 1 :(得分:0)

看起来如果放 throw 它将永远不会返回,如果放 ok 模式将永远不会与 throw 匹配。请参阅具有相似 issue 的主题。 main/1 的逻辑需要改变,例如:

main(Args) ->
    MaybeOk = case Args of
        0 -> throw;
        _ -> ok
    end,
    throw_or_ok(MaybeOk).

main(_Args) ->
    throw_or_ok(_Args).
相关问题