Elixir:在case语句中使用变量
问题描述:
我已经得到了这个case语句,它给出了一个错误'variable constant1 is unused'。它似乎忽略了变量并返回顶部,所以变量显然没有范围。如果我用数字1替换常量,那么它就可以工作。 Elixir的最佳做法是什么?Elixir:在case语句中使用变量
defmodule Main
do
def constant1, do: 1
def constant2, do: 1
def constant3, do: 1
x = 1
y = 0
z = 0
{a, b, c, d} =
case {x, y, z} do
{constant1, constant2, constant3} -> {1, 2, 3, 4}
{constant1, constant2, _} -> {5, 6, 7, 8}
{constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
这里是输出:
warning: variable constant1 is unused
Untitled 9:15
{1, 2, 3, 4}
改变常数变量也不起作用。
答
您已将constant1
定义为函数。当你尝试在模式匹配中使用它时,Elixir希望变量在那里,并且你有错误。人们无法模式匹配功能。
你想要的东西可能是:
defmodule Main do
constant1 = 1
constant2 = 1
constant3 = 1
x = 1
y = 0
z = 0
{a, b, c, d} =
case {x, y, z} do
{^constant1, ^constant2, ^constant3} -> {1, 2, 3, 4}
{^constant1, ^constant2, _} -> {5, 6, 7, 8}
{^constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
#⇒ { 9, 10, 11, 12 }
另外,请记住,模式匹配已定义的值,应该在匹配的前面使用the pin operator ^
,否则代码
a = 42
case x do
a -> ...
end
将覆盖的值为a
,将其设置为值x
(在case
块的范围内,在之外。一将保持42
)随着^
,下面的代码,当且仅x == 42
匹配:
a = 42
case x do
^a -> ...
end
答
回答有关后续问题“如何”,“我可以用全局”等
Elixir(所有已知的函数式语言)都没有“全局”的概念,因为从外部的角度来看,所有东西都是不变的。 真常数正在实现为宏。宏是在编译阶段AST编译,因此可作为常数内匹配:
defmodule Constants do
defmacro constant1 do
quote do: 1
end
defmacro constant2 do
quote do: 1
end
defmacro constant3 do
quote do: 1
end
end
defmodule Main do
require Constants
x = 1
y = 0
z = 0
{a, b, c, d} =·
case {x, y, z} do
{Constants.constant1, Constants.constant2, Constants.constant3} -> {1, 2, 3, 4}
{Constants.constant1, Constants.constant2, _} -> {5, 6, 7, 8}
{Constants.constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
上述工作,因为编译后有没有Constants.constant1
了在Main
代码:有实值:1
S和代码正在运行是:
case {x, y, z} do
{1, 1, 1} -> {1, 2, 3, 4}
{1, 1, _} -> {5, 6, 7, 8}
{1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
希望它能帮助。
非常感谢您的回答。我将如何使用全局常量来代替变量?我尝试使用@ constant1语法,但我得到了一元运算符^的错误无效参数,预计现有变量得到:^ @ constant1 – iphaaw
您不能。 https://github.com/elixir-lang/elixir/issues/2963基本上,这是因为Elixir模块属性在编译时只有_和(不像Erlang)不存在模块中。 – mudasobwa
我可以有一个全局变量吗? – iphaaw