如何在模块变量和局部静态变量之间进行比较时抑制透析器警告?

How can I suppress dialyzer warning on comparison between module variable and local static variable?

Dialyzer 指责试图匹配模块变量的代码:

defmodule Main do
  # -> :demo
  @env Application.get_env(:myproject, :env)

  def run do
    case @env do
      :production -> 1
      _ -> 2
    end
  end
end
lib/myproject/main.ex:6:pattern_match
The pattern can never match the type.

Pattern:
:production

Type:
:demo

怎样才能避免警告,还是每次都这样写?

  def run do
    env = Application.get_env(:myproject, :env)

    case env do
      ...
    end
  end

should I write as below every time?

这取决于您要实现的目标。 dialyzer 很聪明。模块属性是编译时的野兽,它们在编译期间随处计算和替换。在上面的代码片段中进入 BEAM 的是:

defmodule Main do
  def run do
    case :demo do
      :production -> 1
      _ -> 2
    end
  end
end

也就是说,dialyzer 会警告您无法访问的语句,因为它分析了 生成的代码 ,所有宏都已扩展 模块属性已放置。

如果你想根据环境编译出不同的代码,你有几种方法。

  1. 明确禁止透析器警告为 described here
  2. 欺骗透析器(示例可能在 Elixir 核心中找到,我不会将它们粘贴在这里,因为我觉得这个解决方案不够稳健。)
  3. 直接在 case 子句中调用 Application.get_env(:myproject, :env)(或按照您的建议分配给局部变量。)

后一种方法是 IMSO 更可取