首页 > 解决方案 > 如何在模块变量和局部静态变量之间进行比较时抑制透析器警告?

问题描述

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

标签: elixirdialyzer

解决方案


我应该每次都写如下吗?

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

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

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

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

  1. 如此处所述,显式抑制透析器警告。
  2. 欺骗透析器(示例可能在Elixir核心中找到,我不会在此处粘贴这些示例,因为我发现此解决方案不够强大。)
  3. Application.get_env(:myproject, :env)直接在子句中调用case(或按照您的建议分配给局部变量。)

后一种方法是 IMSO可取的。


推荐阅读