2016-09-20 98 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 

希望它能幫助。