Elixir 簡明筆記(十六) --- 控制結構之條件控制

函數式語言常使用模式匹配來做控制結構,但這并不意味著Elixir就沒有通常的if-else結構。在Elixir中,if 卻不是語句而是。這一點在理解宏之前,暫時把他看出語句表達式吧。一般語句沒有返回值,表達式有返回值,elixir中if宏是有返回值的。就像字典結構一樣,elixir提供了好幾個這樣的結構,對于經典的條件結構,elixir同樣也提供了 if unless condcase好幾種方式。

if 宏

if宏比較簡單,和別的編程語言差別不到,其基本語法如下:

if condition do
    ...
else
    ...
end

條件(condition)表達式求值為ture,則執行其下面的代碼,否則執行else里的代碼。當然,如果具體執行的邏輯代碼是一行,則有如下的簡寫成一行
if condition, do: somthing, else: anther_ting

可以通過 h 查看 if的用法

iex(1)> h if

                        defmacro if(condition, clauses)

Provides an if macro. This macro expects the first argument to be a condition
and the rest are keyword arguments.

One-liner examples

┃ if(foo, do: bar)

In the example above, bar will be returned if foo evaluates to true (i.e. it is
neither false nor nil). Otherwise, nil will be returned.

An else option can be given to specify the opposite:

┃ if(foo, do: bar, else: baz)

Blocks examples

Elixir also allows you to pass a block to the if macro. The first example above
would be translated to:

┃ if foo do
┃   bar
┃ end

Notice that do/end becomes delimiters. The second example would then translate
to:

┃ if foo do
┃   bar
┃ else
┃   baz
┃ end

If you want to compare more than two clauses, you can use the cond/1 macro.

iex(2)>

if 本質上是一個宏,這個宏接受參數,第一個參數是 condition,第二個參數可以是一個keyword [do: bar], 只不過[]可以省略,就寫成了 do: bar,keyword列表還可以提供else部分。執行do還是else的邏輯,取決于 condition的求值。if宏的返回值為do或者else執行后的返回值。在尚未了解宏之前,可以把 do else 展成代碼塊(元編程的精髓)。

iex(2)> if 5 > 0, do: :true
true
iex(3)> if 5 < 0, do: :true
nil
iex(4)> if 5 < 0, do: :true, else: :false
false
iex(5)> if 5 < 0, [do: :true, else: :false]
false
iex(6)> if(5 < 0, [do: :true, else: :false])
false
iex(7)> if(5 < 0, [{:do, :true}, {:else, :false}])
false
iex(8)> if 5 > 0 do
...(8)>   :ture
...(8)> else
...(8)>   :false
...(8)> end
:ture

cond

經典的條件控制往往還有if elif else這樣的多路條件。elixir也有類似的,即cond宏。cond做條件Lisp用得很頻繁。cond沒有簡寫模式,其基本形式為:


cond do
  expression_1 ->    
    ...
  expression_2 ->
    ...
    
  ... 

end

如果沒有條件符合,最后會報錯,所以通常的做法是寫一個default的語句:

iex(1)> cond do
...(1)>     1 + 1 == 1 ->
...(1)>         "This will never match"
...(1)>     2 * 2 !=4 ->
...(1)>         "Nor this"
...(1)>     true ->
...(1)>         "This will"
...(1)> end
"This will"

case

cond語句在Lisp中大行其道,elixir更多喜好模式匹配,因此還有case宏可以做多路條件判斷。case的語法也很簡單:

case expression do
  pattern_1 ->
    ...
  pattern_2 ->
    ...
  ... 
end

case使用expression表達式做為模式匹配的右邊,模式匹配成功則執行其代碼塊內容,并返回代碼塊中的返回值。無法匹配的,同樣也會拋出異常, 比正常的模式匹配更高級的一點在于,case的模式可以接受when這樣的gurads語句。

iex(3)> case {:ok, "hello"} do
...(3)>    {:ok, value} when is_number(value) ->
...(3)>       value
...(3)>    {:ok, value} ->
...(3)>       "OK"
...(3)>    true ->
...(3)>       "always true"
...(3)> end
"OK"

以上就是elixir中的條件控制結構,相對而言,還是比較簡單的,和其他語言經典的條件控制非常相似。盡管宏定義的時候,其簡寫方法有點怪。可是宏不就是為了展開進行元編程嘛。實質上這些宏展開了都是標準的條件判斷寫法,可見宏編程的強大。

除了條件控制結構,常用的控制結構就是循環。不同于別的語言,elixir并沒有提供直接用于循環的while,for等循環結構,取而代之的是通過函數的遞歸來實現循環迭代的需求。下一節將會介紹循環的做法---遞歸和迭代。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容