Erlang if 與 case

2022-07-07 15:39 更新

Erlang if 與 case

上面的 find_max_and_min 函數(shù)可以找到溫度的最大值與最小值。這兒介紹一個(gè)新的結(jié)構(gòu) if。If 的語法格式如下:

if
    Condition 1 ->
        Action 1;
    Condition 2 ->
        Action 2;
    Condition 3 ->
        Action 3;
    Condition 4 ->
        Action 4
end

注意,在 end 之前沒有 “;”。條件(Condidtion)的工作方式與 guard 一樣,即測(cè)試并返回成功或者失敗。Erlang 從第一個(gè)條件開始測(cè)試一直到找到一個(gè)測(cè)試為真的分支。隨后,執(zhí)行該條件后的動(dòng)作,且忽略其它在 end 前的條件與動(dòng)作。如果所有條件都測(cè)試失敗,則會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。一個(gè)測(cè)試恒為真的條件就是 true。它常用作 if 的最后一個(gè)條件,即當(dāng)所有條件都測(cè)試失敗時(shí),則執(zhí)行 true 后面的動(dòng)作。

下面這個(gè)例子說明了 if 的工作方式:

-module(tut9).
-export([test_if/2]).

test_if(A, B) ->
    if 
        A == 5 ->
            io:format("A == 5~n", []),
            a_equals_5;
        B == 6 ->
            io:format("B == 6~n", []),
            b_equals_6;
        A == 2, B == 3 ->                      %That is A equals 2 and B equals 3
            io:format("A == 2, B == 3~n", []),
            a_equals_2_b_equals_3;
        A == 1 ; B == 7 ->                     %That is A equals 1 or B equals 7
            io:format("A == 1 ; B == 7~n", []),
            a_equals_1_or_b_equals_7
    end.

測(cè)試該程序:

60> c(tut9).
{ok,tut9}
61> tut9:test_if(5,33).
A == 5
a_equals_5
62> tut9:test_if(33,6).
B == 6
b_equals_6
63> tut9:test_if(2, 3).
A == 2, B == 3
a_equals_2_b_equals_3
64> tut9:test_if(1, 33).
A == 1 ; B == 7
a_equals_1_or_b_equals_7
65> tut9:test_if(33, 7).
A == 1 ; B == 7
a_equals_1_or_b_equals_7
66> tut9:test_if(33, 33).
** exception error: no true branch found when evaluating an if expression
     in function  tut9:test_if/2 (tut9.erl, line 5)

注意,tut9:test_if(33,33) 使得所有測(cè)試條件都失敗,這將導(dǎo)致產(chǎn)生一個(gè) if_clause 運(yùn)行時(shí)錯(cuò)誤。參考 Guard 序列 可以得到更多關(guān)于 guard 測(cè)試的內(nèi)容。

Erlang 中還有一種 case 結(jié)構(gòu)?;叵胍幌虑懊娴?convert_length 函數(shù):

convert_length({centimeter, X}) ->
    {inch, X / 2.54};
convert_length({inch, Y}) ->
    {centimeter, Y * 2.54}.

該函數(shù)也可以用 case 實(shí)現(xiàn),如下所示:

-module(tut10).
-export([convert_length/1]).

convert_length(Length) ->
    case Length of
        {centimeter, X} ->
            {inch, X / 2.54};
        {inch, Y} ->
            {centimeter, Y * 2.54}
    end.

無論是 case 還是 if 都有返回值。這也就是說,上面的例子中,case 語句要么返回 {inch,X/2.54} 要么返回 {centimeter,Y*2.54}。case 語句也可以用 guard 子句來實(shí)現(xiàn)。下面的例子可以幫助你分清二者。這個(gè)例子中,輸入年份得到指定某月的天數(shù)。年份必須是已知的,因?yàn)殚c年的二月有 29 天,所以必須根據(jù)年份才能判斷二月的天數(shù)。

-module(tut11).
-export([month_length/2]).

month_length(Year, Month) ->
    %% 被 400 整除的為閏年。
    %% 被 100 整除但不能被 400 整除的不是閏年。
    %% 被 4 整除但不能被 100 整除的為閏年。
    Leap = if
        trunc(Year / 400) * 400 == Year ->
            leap;
        trunc(Year / 100) * 100 == Year ->
            not_leap;
        trunc(Year / 4) * 4 == Year ->
            leap;
        true ->
            not_leap
    end,  
    case Month of
        sep -> 30;
        apr -> 30;
        jun -> 30;
        nov -> 30;
        feb when Leap == leap -> 29;
        feb -> 28;
        jan -> 31;
        mar -> 31;
        may -> 31;
        jul -> 31;
        aug -> 31;
        oct -> 31;
        dec -> 31
    end
70> c(tut11).
{ok,tut11}
71> tut11:month_length(2004, feb).
29
72> tut11:month_length(2003, feb).
28
73> tut11:month_length(1947, aug).
31
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)