erlang 透析器说函数将永远不会被调用,即使它是

azpvetkf  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(148)

I am using the elixir_talk library. After connecting I want to call a private function once connected to beanstalkd. I just added typespecs and ran Dialyzer (via dialyxir). I get the errors:

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

The minimal example I could find that produces this is

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

If I replace the call to ElixirTalk.connect with a call to spawn instead, Dialyzer no longer reports any problems.

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

Does anyone know why Dialyzer is getting confused here?

bnlyeluc

bnlyeluc1#

看一下源代码,类型规范说第三个参数总是一个整数,即使默认值是atom infinity。因此,调用ElixirTalk. connect时使用infinite timeout是违反类型规范的。在Erlang中,你可以通过将类型指定为timeout()来解决这个问题,它允许整数和infinite;不知道这怎么翻译成长生不老药。-legoscia 5月16日15:56

相关问题