年度最佳代码“不管你们信不信,反正我信了”
最近有段十分流行的代碼,是從江湖傳聞“身懷八蛋”的鐵道部發言人王勇平同志的一句名言:“不管你們信不信,反正我信了……這是生命的奇跡……它就是發生了”所引申出來的。這段代碼雖然只是在調侃,但是圍繞這段代碼也產生了一些討論(如代碼風格,編程規范等等),在此順手記錄一下,就當無聊罷。
這段代碼是這樣的:
代碼與原文的對應關系不言自明,從命名風格上看,我們默認其為Java代碼。話題主要是圍繞在if條件的寫法上。
書寫風格
先來看看它的書寫風格問題。我說這段代碼不是老鳥寫的,因為老鳥不會把一個布爾表達式跟true和false直接判斷,而會寫成:
于是有朋友提出,把布爾表達式跟true或false相比較來的更清晰一些,我表示這話并沒有什么道理,因為這種讀代碼的方式是把視角停留在“數據”層面上:一個布爾表達式返回了布爾型的“數據”,于是把它和另外一個“數據”進行比較。如今的編程都在不斷強調“語義”,“語義”的清晰才是真的清晰。我說Java是一門糟糕的語言,主要原因就是指它的表達能力太差,導致寫出來的代碼體現不出問題的解決方式,讓人們把目光都集中在具體每條語句上了,所謂“見木不見林”。C#等現代語言都在強調“做什么”而不是“怎么做”,語義上就有很大提高了。
回到目前這個具體問題上,if里面的語義是“you.believe(it)”的返回結果,而不是它的值與另外一個布爾常量的比較結果。其實這個觀點我從初中搞信息學競賽時就被老師不斷強調,今天我同樣咨詢了同事,他也贊同我的觀點。如果您還繼續堅持這種寫法不太清晰的話,我只能說“這只是不適應而已,要讓自己適應這類寫法”,很多人還覺得LINQ不清晰呢,小學生還覺得高中數學的解法不清晰呢。
還有朋友認為,作為編碼規范,應該要求這么寫,例如:
就是說,把常量寫在比較操作的左邊,并認為“這樣更有普遍意義”。其實這也沒有必要,這個習慣是從C語言時代遺傳下來的“陋習”。在C語言里,如果把常量寫在比較右側,并且一不小心把“比較”操作符(兩個等號)寫成“賦值”操作符(一個等號),也可以編譯通過,但是結果卻大不相同,這給錯誤排查也會帶來許多麻煩。但是,在如今的語言里已經比C語言做的安全多了,所以沒必要制定這種規范。把一種語言的標準帶入另一種語言不叫做“有普遍意義”,只是多余。
代碼含義
然后要談的便是代碼與那句話的“映射”關系了,再來仔細讀一下這個if子句:
從“需求”上來理解,我認為代碼應該保證if內部的代碼一定會執行。那么現在這個需求肯定會滿足嗎?不一定,因為you.believe方法可能是有副作用的:如果它第一次調用返回false,而第二次調用時返回true,則if內部的代碼就會整段略過,這顯然不是鐵道部王發言人的意圖。因此,有同學提議代碼應該是這樣的:
這么做的確可以忽略you.believe(it)的結果,因為它已經被短路了根本不會執行。可能它也能滿足需求,但我想更合理的做法可能應該是:
這段代碼與之前的區別就在于you.believe(it)一定會被調用一次,但是無所謂其結果是如何,這充分符合天朝某些部門喜歡裝摸作樣“咨詢民意”的狀況。
擴展思考
最后再來一道擴展思考題吧:有人把“你愛,或者不愛我,愛就在那里,不增不減”寫成了一段C#代碼:
有人說,這段代碼的if條件本身應該被編譯器優化掉,因此會直接執行if內部的代碼。還有人說,if內部的代碼也會被編譯器優化掉。您怎么看,為什么呢?
————
編輯?∑Gemini
?來源:算法數學之美
?泰勒定理的奇聞軼事
?丘成桐:漫談微分幾何
?Leibniz 如何想出微積分?(一)
?線性相關和秩的物理意義
?數學史上你認為最丑陋的公式是什么?
?陶哲軒談什么是好的數學
?田淵棟:數學的用處(下篇)
?你絕對沒想過原來數學家這么流氓,一言不合就進行暴力證明
?世界上最牛的五篇博士論文
?數學中有哪些巧合讓人眼前一亮?
?算法立功!清華畢業教授美國被搶車,警察無能為力自己用“貪心算法”找回
?學術史上的奇文:怎樣用數學抓獅子
?臺大教授的反思:最難的一課 我們卻沒教給學生
?麻省理工學院(MIT)研究生學習指導—— 怎樣做研究生
?分享 數學,常識和運氣 ——投資大師詹姆斯·西蒙斯2010年在MIT的講座
算法數學之美微信公眾號歡迎賜稿
稿件涉及數學、物理、算法、計算機、編程等相關領域,經采用我們將奉上稿酬。
投稿郵箱:math_alg@163.com
總結
以上是生活随笔為你收集整理的年度最佳代码“不管你们信不信,反正我信了”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 继北大“鸿hao之志”后,清华出现“热列
- 下一篇: 【文末有福利】5个字极简入门朴素贝叶斯模