2016-09-20 80 views
3

我已经得到了这个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} 

改变常数变量也不起作用。

回答

2

您已将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 
+0

非常感谢您的回答。我将如何使用全局常量来代替变量?我尝试使用@ constant1语法,但我得到了一元运算符^的错误无效参数,预计现有变量得到:^ @ constant1 – iphaaw

+0

您不能。 https://github.com/elixir-lang/elixir/issues/2963基本上,这是因为Elixir模块属性在编译时只有_和(不像Erlang)不存在模块中。 – mudasobwa

+0

我可以有一个全局变量吗? – iphaaw

1

回答有关后续问题“如何”,“我可以用全局”等

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 

希望它能帮助。