Dialyzer 说函数永远不会被调用,即使它是

Wil*_*ell 7 erlang elixir dialyzer

我正在使用 elixir_talk 库。连接后,我想在连接到 beanstalkd 后调用私有函数。我刚刚添加了 typespecs 并运行了 Dialyzer(通过dialyxir)。我收到错误:

my_module.ex:3: The specification for 'Elixir.MyModule':f/0 states that the function might also return 'ok' | {'error',_} but the inferred return is none()
my_module.ex:4: Function f/0 has no local return
my_module.ex:14: Function g/1 will never be called
Run Code Online (Sandbox Code Playgroud)

我能找到的产生这个的最小例子是

defmodule MyModule do
  @spec f() :: :ok | {:error, term}
  def f() do
    case ElixirTalk.connect('127.0.0.1', 11300) do
      {:ok, conn} ->
        g(conn)
      {:error, err} ->
        {:error, err}
    end
  end

  @spec g(pid) :: :ok
  defp g(pid) do
    :ok
  end
end
Run Code Online (Sandbox Code Playgroud)

如果我更换呼叫ElixirTalk.connect与到呼叫spawn相反,透析器不再报告任何问题。

defmodule MyModule do
  @spec f() :: :ok
  def f() do
    x = spawn fn -> :done end
    g(x)
  end

  @spec g(pid) :: :ok
  defp g(pid) do
    :ok
  end
end
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么透析器在这里变得混乱?

Sin*_*inc 1

查看源代码,类型规范表明第​​三个参数始终是整数,即使默认值是原子无穷大。因此,无限超时调用 ElixirTalk.connect 将违反类型规范。在 Erlang 中,你可以通过将类型指定为 timeout() 来解决这个问题,它允许整数和无穷大;不知道这如何转化为 Elixir。\xe2\x80\x93 乐高西亚 2016-05-16 15:56

\n