erlang 如何让透析器接受对有意抛出的函数的调用?

vxqlmq5t  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(146)

我有一个函数,当它的第一个参数是atom 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的调用(保证会抛出)?

chhkpiq4

chhkpiq41#

遗憾的是,目前没有明确的方法通过质量标准将其标记为透析器可接受。
但是,也许您可以使用忽略警告注解。

jvlzgdj9

jvlzgdj92#

看起来像是如果将放置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).

相关问题