Elixir:在case语句中使用变量

时间:2016-09-20 08:48:59

标签: case constants elixir

我有这个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}

将常量更改为变量也不起作用。

2 个答案:

答案 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

希望它有所帮助。