為什么我不會舍棄 Python 投奔 Go 語言
本文的作者:Russ Cox
Russ Cox畢業于麻省理工和哈佛大學,曾在貝爾實驗室參與過Plan 9 和 Unix操作系統的開發,最近在google,主要開發Go語言。
最近關于Go語言的話題很多,本月剛好是Go語言誕生3周年。這個語言在谷歌巨人的推動下最終很可能成為今后的主流語言。如果你想簡單了解一下Go語言,這里有Go語言官方網站提供的一個很簡單的中文版的“Go語言半小時速成教程”,不妨一看。
下面是譯文內容:
最近,由于一篇“為什么我不會舍棄Python投奔Go語言(英文)”的博客,我收到了大量的郵件,這篇文章中,作者說Go語言除了“用返回值來處理異常錯誤”這點外,其它的都非常好。我想寫出一點東西,解釋一下Go語言為什么這樣做,這會對大家都有用。
在Go語言中,規定的方式是,函數返回錯誤信息。這沒什么。如果一個文件并不存在,op.Open函數會返回一個錯誤信息。這沒什么。如果你向你一 個中斷了的網絡連接里寫數據,net.Conn里的Write方法會返回一個錯誤。這沒什么。這種狀況在這種程序中是可以預料到的。這種操作就是容易失 敗,你知道程序會如何運行,因為API的設計者通過內置了一種錯誤情況的結果而讓這一切顯得很清楚。
從另一方面講,有些操作基本上不會出錯,所處的環境根本不可能給你提示錯誤信息,不可能控制錯誤。這才是讓人痛苦的地方。典型的例子;一個程序執行 x[j],j值超出數組邊界,這才痛苦。像這樣預料之外的麻煩在程序中是一個嚴重的bug,一般會弄死程序的運行。不幸的是,由于這種情況的存在,我們很 難寫出健壯的,具有自我防御的服務器——例如,可以應付偶然出現的有bug的HTTP請求處理器時,不影響其他服務的啟動和運行。為解決這個問題,我們引 入了恢復機制,它能讓一個go例程從錯誤中恢復,服務余下設定的調用。然而,代價是,至少會丟失一個調用。這是特意而為之的。引用郵件中的原話:“這種設 計不同于常見的異常控制結構,這是一個認真思考后的決定。我們不希望像java語言里那樣把錯誤和異常混為一談。”
我剛開始提到的那篇文章里問“為什么數組越界造成的麻煩會比錯誤的網址或斷掉的網絡引出的問題要大?”答案是,我們沒有一種內聯并行的方法來報告在執行x[j]期間產生的錯誤,但我們有內聯并行的方法報告由錯誤網址或網絡問題造成的錯誤。
使用Go語言中的錯誤返回模式的規則很簡單:如果你的函數在某種情況下很容易出錯,那它就應該返回錯誤。當我調用其它的程序庫時,如果它是這樣寫的,那我不必擔心那些錯誤的產生,除非有真正異常的狀況,我根本沒有想到需要處理它們。
有一個你需要記在心里的事情是,Go語言是為大型軟件設計的。我們都喜歡程序簡潔清晰,但對于一個由很多程序員一起開發的大型軟件,維護成本的增加 很難讓程序簡潔。異常捕捉模式的錯誤處理方式的一個很有吸引力的特點是,它非常適合小程序。但對于大型程序庫,如果對于一些普通操作,你都需要考慮每行代 碼是否會拋出異常、是否有必要捕捉處理,這對于開發效率和程序員的時間來說都是非常嚴重的拖累。我自己做開發大型Python軟件時感受到了這個問題。 Go語言的返回錯誤方式,不可否認,對于調用者不是很方便,但這樣做會讓程序中可能會出錯的地方顯的很明顯。對于小程序來說,你可能只想打印出錯誤,退出 程序。對于一些很精密的程序,根據異常的不同,來源的不同,程序會做出不同的反應,這很常見,這種情況中,try + catch的方式相對于錯誤返回模式顯得冗長。當然,Python里的一個10行的代碼放到Go語言里很可能會更冗長。畢竟,Go語言主要不是針對10行 規模的程序的。
Raymond Chen的文章是我讀到過的最好的用來解釋異常捕捉模式里問題的文章:
就是要說明這一點:Go語言程序員認為,把error作為一種內置的類型是非常重要的。
Russ
附言
有時,你會發現,一種非本地的goto語句被當作錯誤恢復的方法,就像C語言里的longjmp 和 setjmp。這也不錯,但最好只在內部用。如果調用者需要知道錯誤恢復的走向,那你的這種方式就不好了。
[本文英文原文鏈接:Why Im not leaving Python for Go ]
來自: 外刊IT評論 http://www.aqee.net/