Clojure 學(xué)習(xí)筆記 :9 條件分支結(jié)構(gòu)

Clojure 零基礎(chǔ) 學(xué)習(xí)筆記 條件語句 分支控制


順序結(jié)構(gòu)、循環(huán)結(jié)構(gòu)讨便、分支結(jié)構(gòu) --- 程序的三大結(jié)構(gòu)

條件控制是一種基本的需求置济,我們經(jīng)常能遇見需要針對(duì)不同內(nèi)容進(jìn)行特定處理的情況。這次我們就來看一下 Clojure 中幾種常見的條件分支鲫剿。

首先看一下最基本的 if

=> (if true
        1
        0)
1

不難看出银室,if 接受三個(gè)參數(shù)涂佃,第一個(gè)參數(shù)是一個(gè)布爾值,如果第一個(gè)參數(shù)為 true蜈敢,則 if 的值就是第二個(gè)參數(shù)的值辜荠;如果第一個(gè)參數(shù)為 false,則 if 的值就是第三個(gè)參數(shù)的值抓狭。很簡單伯病。

不過這里特別說明一個(gè)細(xì)節(jié),Clojure 中所有的表達(dá)式都有值否过。if 也不例外午笛,它也有值。if 的值是由它第一個(gè)參數(shù)的真假所決定的叠纹,這也是它稱為條件結(jié)構(gòu)的原因季研。這使得你可以用統(tǒng)一的編程思想去寫 Clojure 代碼敞葛,把表達(dá)式作為一個(gè)值誉察,放在你需要的任何位置,繼續(xù)作為一個(gè)值來代入下一步計(jì)算惹谐。
相反的持偏,在其它很多語言里,并不是所有的式子都有值氨肌。如果你曾學(xué)習(xí)過 C鸿秆、Java 等語言,會(huì)發(fā)現(xiàn) if 語句本身并沒有值怎囚,僅僅起到控制程序走向的功能卿叽。Clojure 中的 if 反而更像 C、Java 里的三元運(yùn)算式恳守。

我們?cè)囍鴮懸粋€(gè)函數(shù)來做這樣的事情:傳入一個(gè)整數(shù)考婴,打印這個(gè)數(shù)字是奇數(shù)還是偶數(shù)。

=> (defn odd-or-even
        [num]
        (if (= (mod num 2) 0)
            (println num "是偶數(shù)")
            (println num "是奇數(shù)")))
#'user/odd-or-even

=> (odd-or-even 1024)
1024 是偶數(shù)
nil

這里可以觀察到催烘,由于 (= (mod num 2) 0) 的值為 true沥阱,所以執(zhí)行了 (println num "是偶數(shù)"),但是 println 的值為 nil伊群,所以 if 的值也就變成了 nil考杉。
這里有個(gè)小問題策精,如果傳入的是一個(gè)小數(shù),我們的程序會(huì)錯(cuò)誤的認(rèn)為它是一個(gè)奇數(shù)崇棠。

Clojure 本身提供了一個(gè)返回布爾型的函數(shù) even? 用來判斷一個(gè)數(shù)字是不是偶數(shù)咽袜,如果是偶數(shù)則返回 true,不是偶數(shù)則返回 false枕稀。所以我們也可以這么寫:

(defn odd-or-even
        [num]
        (if (even? num)
            (println num "是偶數(shù)")
            (println num "是奇數(shù)")))

這樣如果你傳入一個(gè)小數(shù)酬蹋,它就會(huì)報(bào)錯(cuò)提示你 “參數(shù)必須是整數(shù)”。

Clojure 還提供了一個(gè) if-not 函數(shù)抽莱,用來做和 if 完全相反的事情范抓。


如果遇見更為復(fù)雜的問題,比如判斷考試成績的優(yōu)良中差食铐,當(dāng)然匕垫,你可以通過嵌套多層 if 來處理。不過 Clojure 提供了另外一個(gè)方便多層次判斷的東西 --- cond虐呻。

我們來看看如何使用 cond 來解決判斷成績優(yōu)良中差的問題象泵。

=> (defn rating
            [score]
            (cond
                (>= score 90) "優(yōu)秀",
                (>= score 80) "良好",
                (>= score 70) "中等",
                (>= score 60) "及格",
                (< score 60) "較差",))
#'user/rating

=> (println (rating 78))
中等
nil

由上面的例子我們可以總結(jié)出 cond 的用法,它接受若干對(duì)參數(shù)斟叼,每一對(duì)參數(shù)分別是布爾型的表達(dá)式和另一個(gè)表達(dá)式偶惠。cond 會(huì)由上至下的判斷每個(gè)布爾表達(dá)式,一旦判斷為 true朗涩,則 cond 的值就會(huì)變成判斷為 true 后面所跟表達(dá)式的值忽孽。如果判斷到末尾依然沒有任何表達(dá)為 true,則 cond 的值等于 nil 谢床。

注意兄一,一旦 cond 發(fā)現(xiàn) true,會(huì)停止繼續(xù)解析下面的式子识腿,所以如果式子的先后順序出現(xiàn)問題就會(huì)出現(xiàn)意外:

=> (defn rating
            [score]
            (cond
                (>= score 60) "及格",
                (>= score 90) "優(yōu)秀",
                (>= score 80) "良好",
                (>= score 70) "中等",
                (< score 60) "較差",))
#'user/rating

=> (println (rating 98))
及格
nil 

你還可以提供一個(gè) :default 值來確保沒有任何匹配時(shí)出革,返回你所設(shè)置的默認(rèn)值:

=> (defn rating
            [score]
            (cond
                (>= score 90) "優(yōu)秀",
                (>= score 80) "良好",
                (>= score 70) "中等",
                (>= score 60) "及格",
                :default "較差",))
#'user/rating

=> (println (rating -10))
較差
nil 

有些時(shí)候我們需要處理一些固定有限的情況,比如把阿拉伯?dāng)?shù)字轉(zhuǎn)換成中文大寫數(shù)字渡讼,處理一些狀態(tài)碼骂束,等。
這個(gè)時(shí)候 case 是最佳選擇成箫。(相當(dāng)于 C / Java 等語言中的 switch

=> (defn arabic-num-to-chinese-num
            [arabic-num]
            (case arabic-num 
              1 "壹",
              2 "貳",
              3 "叁",
              4 "肆",
              5 "伍",
              6 "陸",
              7 "柒",
              8 "捌",
              9 "玖",
              0 "零",
              "未知"))
=> #'user/arabic-num-to-chinese-num

=> (println (arabic-num-to-chinese-num 8))
捌
nil

case 的用法也很簡單直觀展箱,它的第一個(gè)參數(shù)是一個(gè)表達(dá)式,余下參數(shù)是一些鍵值對(duì)伟众。在這些鍵值對(duì)中析藕,首先尋找第一個(gè)參數(shù)的值所對(duì)應(yīng)的鍵,case 的值就等于我們找到的鍵所對(duì)應(yīng)的值。需要注意账胧,如果出現(xiàn)找不到匹配的情況竞慢,case 不會(huì)返回 nil,而是會(huì)報(bào)錯(cuò)治泥。所以我們需要在最后一行加上一個(gè)默認(rèn)值筹煮,就如同上面例子中的 "未知" 。一旦出現(xiàn)無法匹配的情況居夹,case 的值就是我們所設(shè)定的默認(rèn)值败潦。

需要特別注意的是,case 中所接受的鍵值對(duì)中的 鍵准脂,一定是直接寫出的常量劫扒,而不能是需要計(jì)算才能得出值的表達(dá)式。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狸膏,一起剝皮案震驚了整個(gè)濱河市沟饥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌湾戳,老刑警劉巖贤旷,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砾脑,居然都是意外死亡幼驶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門韧衣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盅藻,“玉大人,你說我怎么就攤上這事汹族∠羟螅” “怎么了其兴?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵顶瞒,是天一觀的道長。 經(jīng)常有香客問我元旬,道長榴徐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任匀归,我火速辦了婚禮坑资,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘穆端。我一直安慰自己袱贮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布体啰。 她就那樣靜靜地躺著攒巍,像睡著了一般嗽仪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柒莉,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天闻坚,我揣著相機(jī)與錄音,去河邊找鬼兢孝。 笑死窿凤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的跨蟹。 我是一名探鬼主播雳殊,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窗轩!你這毒婦竟也來了相种?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤品姓,失蹤者是張志新(化名)和其女友劉穎寝并,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腹备,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衬潦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了植酥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镀岛。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖友驮,靈堂內(nèi)的尸體忽然破棺而出漂羊,到底是詐尸還是另有隱情,我是刑警寧澤卸留,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布走越,位于F島的核電站,受9級(jí)特大地震影響耻瑟,放射性物質(zhì)發(fā)生泄漏旨指。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一喳整、第九天 我趴在偏房一處隱蔽的房頂上張望谆构。 院中可真熱鬧,春花似錦框都、人聲如沸搬素。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熬尺。三九已至何荚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猪杭,已是汗流浹背餐塘。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留皂吮,地道東北人戒傻。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像蜂筹,于是被迫代替她去往敵國和親需纳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容