[go語言]Russ Cox回應“Why I'm not leaving python for go”

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

註:這是Russ Cox解釋Go錯誤和異常機制的一篇文章[1],網上已經有翻譯文章[2],但是我認為有一些錯誤和不夠準確的地方,所以自己花了一些時間又翻譯了一遍。

    [1]https://plus.google.com/116810148281701144465/posts/iqAiKAwP6Ce

    [2]http://www.aqee.net/response-to-why-im-not-leaving-python-for-go/

 以下是譯文:

我收到了許多郵件,這些郵件提到最近一篇名為“為什麼我不會放棄Python投向Go”[1]的部落格文章。在這篇文章裡,作者說Go除了“用傳回值來進行錯誤處理”這點不好,其他都非常不錯。我想寫一些東西談談Go為什麼會用傳回值來進行錯誤處理,可能會對大家有所協助。

Go語言的規則是函數返回錯誤,這些函數不會panic[2]。如果一個檔案找不到,os.Open返回一個錯誤,它不會panic;如果你向一個中斷的網路連接寫資料,net.Conn系列類型[3]的Write函數返回一個錯誤,它們不會panic。這些狀態在這樣的程式裡都是可以預期的。你知道這些操作可能會失敗,因為API的設計者已經用返回的錯誤清楚地表明了這一點。

另一方面,也有一些操作幾乎不可能失敗,而且在那種境地下沒有辦法通知錯誤,也無法繼續執行,這樣的情況就適用panic。一個典型的例子是如果一個程式計算x[j],但是j已經越界了,這部分代碼就會導致panic。像這樣一個不可預期的panic是程式中一個嚴重的bug,在預設情況下它會殺死進程。不幸的是,這會使得很難寫出健壯、防錯的伺服器程式,例如需要能夠處理偶爾有一些錯誤的HTTP請求,同時保證伺服器的其他部分繼續運行。為瞭解決這樣的問題,我們引入了recover,它允許一個goroutine能從發生在幾個函數調用幀之下的panic中恢複執行。但是,panic會導致至少丟失一個函數調用幀[4]。我們是特意這麼設計的。引用郵件原文:“這個提案與通常作為流程式控制制的異常模型不同,但這是一個謹慎的決定。我們不想鼓勵程式員像在java語言那樣混淆錯誤和異常”。

我提到的那篇部落格在文章開始問道“為什麼越界的數組會導致panic而錯誤的格式化字串或者中斷的網路連接不會?”答案是沒有一種帶內的方法在計算x[j]時報告數組越界的錯誤,但是有帶內[6]的方法來報告錯誤的格式化字串或者中斷的網路連接的錯誤[7]。(關于格式化字串錯誤處理的設計很有意思,但它和這裡的討論沒有關係)

規則很簡單:如果你的函數無論如何有可能失敗,它就應該返回一個錯誤。當我調用其他package的函數時,如果這個函數實現的很好,我不需要擔心它會panic,除非有真正的異常情況發生,即使那樣也不應該是我去處理它。

有件事你要意識到:Go是為編寫大型軟體而設計的。我們喜歡讓程式保持簡潔,而不是為大配量序員編寫的大型程式不斷投入維護成本。基於異常的錯誤處理的一個誘惑是,對於小的程式它工作得很好。但是在一個龐大的程式碼程式庫裡,對於每一行代碼,每一個普通的操作,都需要考慮它們是否會觸發一個需要處理的異常。這對於生產效率和工程時間是個很大的拖累。我自己在編寫大型Python程式時就遇到這樣的問題。必須承認,Go語言裡函數返回錯誤對於調用者來說並不方便,但它們很明白地表明了程式和類型系統裡發生錯誤的可能性。當遇到函數返回錯誤時,小程式可能只想列印出錯誤然後退出程式;但是更精心設計的程式通常會根據不同的錯誤來源作出不同的處理。在這種情況,try和catch的處理方式會比顯式的錯誤傳回值處理更冗長。雖然Python語言的10行代碼用Go語言來實現確實可能會更冗長,但是,Go語言的首要目標不是編寫10行代碼的程式。

關於用異常來進行錯誤處理的陷阱的文章中,Raymond Chen的文章是我見過的最好的:

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

一言蔽之:Go語言的開發人員[8]認為,錯誤類型是如此重要以至於我們把它作為一種內建類型。

附註:偶爾你會看到panic和recover用於作為一些函數間的goto,像C語言裡的longjmp和setjmp那樣。這也挺好,但這應該只用在你自己package裡,如果你的package的調用者需要知道這樣的行為,那你就是錯誤地使用了panic和recover。

[1]http://uberpython.wordpress.com/2012/09/23/why-im-not-leaving-python-for-go/

[2]譯註:panic這裡指go語言的一種異常處理機制,用來表明出現嚴重的程式錯誤。

[3]譯註:原文為net.Conn's,指net.UDPConn,net.TCPConn, net.UnixConn等一些列類型

[4]譯註:在發生panic的函數中,餘下的代碼不會被執行到,執行流程直接跳出當前函數。

[5]譯註:原文為in-band

[6]譯註:“帶內”的原文是in-band,一種通訊術語。如果可以從同一個渠道獲得資訊,就是帶內(in-band);如果需要從另外一個渠道獲得資訊就是帶外(out-of-band)。這裡RussCox借用來指獲得資訊的方式,因為x[j]如果出錯,在文法語句上沒有辦法設定一個變數或者其他語句來直接獲得錯誤資訊,因此說沒有帶內的方法;而對函數而言,資料和出錯資訊都可以從傳回值獲得,因此是帶內的方法。

[7]譯註:譯者認為這裡的意思是沒有途徑在計算x[j]時擷取錯誤資訊,而處理錯誤的格式化字串或者中斷的網路連接時可以通過函數傳回值獲得錯誤資訊。

[8]譯註:原文為Go developers,應為實現go語言的人,而不是使用go語言的人。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.