如何避免在``其他''其他''语句中避免透析中的“永远无法匹配”的错误



我有以下代码:

@spec test_pass(String.t) :: (:failed | {:ok, map()})
def test_pass(pass) do
  db_user = %{password_hash: @hash_for_foo}
  with {:ok, ^db_user} <- Comeonin.Argon2.check_pass(db_user, pass) do
    {:ok, db_user}
  else
    _ -> :failed
  end
end

和Dyalizer为我提供了"永远无法匹配的错误":

⟨my_file⟩.ex:25: The pattern {'ok', _} can never match the type {'error',<<_:64,_:_*8>>}

我的问题是,为什么?我知道它无法匹配,我实际上不在乎,这就是为什么我首先使用with的原因。所有非匹配案例均在else中处理。

如何更改dialyzer的代码?

不是寻找@dialyzer {:nowarn_function, …}。我已经在else主体中使用{:error, _} -> …表达式进行了尝试,但无济于事。

erlang/elixir版本(elixir -v(:

Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.6.1 (compiled with OTP 19)

Argon.check_pass/2是外部的,来自 Comeonein

我检查了comeonin,并在其上运行mix dialixier,并报告了几个no local return错误。

dialyzer非常不友好。但是,如果它报告了错误,则意味着基于您已经注释函数的各种类型规范,因此,它与您的实际用法矛盾。

当透明师抱怨{'error',<<_:64,_:_*8>>}时,这意味着Argon2.check_pass对其本身具有一些矛盾的类型规格,或者可能会更深入。透利的能力不是很友好,可以准确地指出矛盾的地方以及为什么会发生矛盾。

由于我无法完全访问您的代码,以解决问题,最多可以指出您遵循几个步骤:

  1. 如果Argon2.check_pass具有明确的@spec注释,请评论一下,看看Dialyzer是否仍然抱怨。

  2. 如果投诉消失了,请用any修改@spec注释的各个部分,直到出于识别目的而解决该问题。因此,该问题将在此解决,或者您需要在Argon2.check_pass所依赖的其他功能中进行更深入的研究可能是问题的原因。

  3. 如果1.失败,则将定义Argon2.check_pass的函数复制为私人函数:tmp_check_pass,看看如何改变问题。

4.如果需要,您可能需要介绍更多Argon2.check_pass依赖的tmp_...功能以隔离投诉的根本原因。在此之前,首先尝试评论Argon2.check_pass的任何支持功能的所有@spec注释,并相应地应用点1。

最终,您将到达代码中的特定点,根据您提供给Dialyzer的规格,某些使用代码违反了IT:类型{'error',<<_:64,_:_*8>>}

这里的关键想法是试图隔离投诉的根本原因,而透视遗憾的是,这并不是在不时为您指出的问题。

作为另一个问题:dialyzer通常永远是错误的&quot&quot',但我不知道我的@spec是如何不正确的,透明师检测到您的Comeonin.Argon2.check_pass()呼叫永远不会返回确定,所以。..

我还没有解决方案,只想澄清原因。

相关内容

最新更新