我正在使用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
我能找到的最小例子是
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
如果我通过拨打ElixirTalk.connect
来取代对spawn
的通话,则Dialyzer不再报告任何问题。
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
有谁知道为什么Dialyzer在这里感到困惑?
答案 0 :(得分:0)
查看源代码,类型规范说第三个参数始终是整数,即使默认值是原子无穷大。因此,对 ElixirTalk.connect 的无限超时调用将违反类型规范。在 Erlang 中,你可以通过将类型指定为 timeout() 来解决这个问题,它允许整数和无穷大;不知道这如何转化为 Elixir。 – Legoscia 2016 年 5 月 16 日 15:56