elixir - 如何在模块变量和局部静态变量之间进行比较时抑制透析器警告?
问题描述
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
解决方案
我应该每次都写如下吗?
这取决于您要达到的目标。dialyzer
很聪明。模块属性是编译时的野兽,它们在编译期间到处被计算和替换。在上面的片段中进入 BEAM 的内容是:
defmodule Main do
def run do
case :demo do
:production -> 1
_ -> 2
end
end
end
也就是说,dialyzer
会警告您有关无法访问的语句,因为它会分析生成的代码,并扩展了所有宏并放置了模块属性。
如果您想要根据环境不同的编译代码,您有几种方法。
- 如此处所述,显式抑制透析器警告。
- 欺骗透析器(示例可能在Elixir核心中找到,我不会在此处粘贴这些示例,因为我发现此解决方案不够强大。)
Application.get_env(:myproject, :env)
直接在子句中调用case
(或按照您的建议分配给局部变量。)
后一种方法是 IMSO可取的。