我有这个case语句,它给出了一个错误'变量constant1未使用'。它似乎忽略了变量并返回顶线,因此变量显然没有范围。如果我用数字1替换常量,那么它可以工作。在Elixir中这样做的最佳方式是什么?
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}
将常量更改为变量也不起作用。
答案 0 :(得分: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
块的范围内,{{1}之外} \ n将保留case
。)使用42
,以下代码将仅匹配^
:
x == 42
答案 1 :(得分:3)
回答有关“如何”,“我可以使用全局变量”等的后续问题。
Elixir(因为所有已知的函数式语言)都没有“全局”的概念,因为从外部的角度来看,一切都是不可变的。 真常量正在以宏的形式实现。宏在编译阶段编译为AST,因此可以在match:中用作常量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
希望它有所帮助。