自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

代碼中的Goto真的那么不招人喜歡么?

開發(fā) 開發(fā)工具
在程序代碼中,我們?yōu)槭裁词褂胓oto,或者,我們?yōu)槭裁床辉撌褂胓oto呢?本文將討論代碼中的Goto真的那么不招人喜歡么?

幾日前在Cafe午餐的時(shí)候,大家聊起一些在Windows操作系統(tǒng)源代碼庫中曾經(jīng)看到過的一些趣聞逸事,比如那個(gè)著名的“becauseExchangeisamoron”(正好這天公司的Exchange服務(wù)器巨慢,所以大家更是大發(fā)一笑)的注釋。這其中有人提到Windows代碼中大量使用goto語句的這個(gè)事,這讓我想起這樣一個(gè)有趣的問題:

在程序代碼中,我們?yōu)槭裁词褂胓oto,或者,我們?yōu)槭裁床辉撌褂胓oto呢?

我曾經(jīng)不止一次地聽某某義正言辭地向我宣傳goto是邪惡的,但如果我追問這么說的理由為何時(shí),通常的答案都是模模糊糊的人云亦云之類的回答。大部分的理由都會(huì)指出goto破壞了程序的可讀性和可維護(hù)性,如果代碼里到處都是goto來goto去,到***誰都很難搞清程序goto到哪一個(gè)地方了。

這看似頗有道理的說辭其實(shí)充滿了迂腐的書生氣。稍微有點(diǎn)常識(shí)的程序員,難道真會(huì)如此到處使用goto么?顯然不會(huì)。如果說真的有那么一位程序員是到處在用goto把他的程序邏輯拼接起來的話,那我想他不是天才(匯編寫太多了,到處都要自己跳轉(zhuǎn))就是無知(完全無法結(jié)構(gòu)化自己的算法思路)。而軟件開發(fā)作為一個(gè)工程行業(yè)經(jīng)過這么多年的發(fā)展,現(xiàn)實(shí)中已經(jīng)很少會(huì)真的有這種濫用goto的現(xiàn)象了。這當(dāng)然也要感謝于那些關(guān)于goto邪惡性的大力宣傳,大家上proceduralprogramming***課開始,就被反復(fù)灌輸了“不要用goto,不要用goto”的觀念。

那為什么Windows操作系統(tǒng)代碼中大量使用了goto?是不是微軟總部都雇傭了些爛人,大家都在混飯吃?還是說對(duì)于goto的使用是其實(shí)很有選擇性的?而從當(dāng)年goto的大量出現(xiàn)到今天這個(gè)關(guān)鍵詞在使用C#或Java寫就的程序中幾乎絕跡,這一切,其實(shí)都是有其歷史背景和含義的?

要回答這些問題,我們首先討論一下goto在Windows操作系統(tǒng)源碼中的使用。如果仔細(xì)觀察一下的話,你會(huì)發(fā)現(xiàn)goto的使用其實(shí)都是在一種很特定的場合,那就是:系統(tǒng)資源的回收和釋放。這里,系統(tǒng)資源可能是一塊字符串內(nèi)存,可能是某個(gè)內(nèi)核對(duì)象(比如event或mutex)的句柄(handle),也可能是更復(fù)雜一些的數(shù)據(jù)結(jié)構(gòu)。所以,goto出現(xiàn)的代碼段,通常有這樣的結(jié)構(gòu):

  1. voidFunc()...{  
  2. ...Magic::Initialize();  
  3. BSTRsomeString=::SysAllocString(L"Somerandomstring");  
  4. hr=CallSomeAPI();  
  5. if(FAILED(hr))  
  6. gotoEXIT;...  
  7. hr=CallSomeOtherAPI();if(FAILED(hr))  
  8. gotoEXIT;  
  9. ...  
  10. EXIT:Magic::Uninitialize();  
  11. ::SysFreeString(someString);  
  12. ...  

如此便不難理解為什么goto在這種特定情況下可以簡化代碼編寫的結(jié)構(gòu),使之更清晰易懂了。試想如果不試用goto,我們的代碼就會(huì)變成:

  1. HRESULTFunc(){  
  2. ...  
  3. Magic::Initialize();  
  4. BSTRsomeString=::SysAllocString(L"Somerandomstring");  
  5. hr=CallSomeAPI();  
  6. if(FAILED(hr))  
  7. {Magic::Uninitialize();  
  8. ::SysFreeString(someString);  
  9. returnhr;  
  10. }  
  11. ...hr=CallSomeOtherAPI();  
  12. if(FAILED(hr))  
  13. {  
  14. Magic::Uninitialize();  
  15. ::SysFreeString(someString);  
  16. returnhr;  
  17. }  
  18. ...returnS_OK;  

要做回收處理的資源越多,這樣的寫法就顯得越冗長,因此goto在這里是很自然的一種選擇。

但隨著面向?qū)ο蟮木幊棠J剑∣bject-OrientedProgrammingParadigm)逐漸地開始取代過程式編程(ProceduralProgramming),程序員開始發(fā)現(xiàn)有一種更好的模式(Pattern)可以用來取代goto,那就是RAII(ResourceAcquisitionIsInitialization)模式(“資源分配與初始化同步”)。RAII的主要思想在于兩點(diǎn):1.對(duì)象在且一定在被分配或構(gòu)造(construct)的時(shí)候同時(shí)被初始化,這樣就避免了資源在沒有被適當(dāng)初始化前就被用戶調(diào)用。2.對(duì)象在被析構(gòu)(destruct)的時(shí)候釋放所占有的資源,這樣就防止了資源泄漏。這個(gè)模式最為大家所熟知的應(yīng)用可能就是C++標(biāo)準(zhǔn)庫或者COM編程中隨處可見的“聰明指針”(smartpointer)了。比如在上面的例子中,我們就可以定義一個(gè)MagicPtr的類,然后在類的構(gòu)造函數(shù)里做Initialize,在析構(gòu)函數(shù)里做Uninitialize。而對(duì)于BSTR,微軟已經(jīng)提供了相應(yīng)的類了,那就是_bstr_t

利用goto來釋放資源在proceduralprogramming的時(shí)代是一個(gè)自然的選擇,所以在Windows的源代碼中你會(huì)看到goto的蹤影,因?yàn)閃indows在OO思想大行其道之前就已經(jīng)存在多年了。但隨著OOP的深入人心,遵循RAII來管理資源就成為了最自然的選擇。

另一個(gè)重要的原因,就是異常處理(exceptionhandling)概念的興起。goto雖然可以很干凈地解決過程式資源回收的問題,但卻對(duì)異常這個(gè)東東沒有很好的解決方法。比如上面的程序要是哪里拋出一個(gè)異常的話,那goto的部分就根本不會(huì)被執(zhí)行了。而另一方面,RAII卻能很好地解決這個(gè)問題,因?yàn)樵趯?duì)象離開定義域之前(不管是return了還是exceptionthrown了),析構(gòu)函數(shù)都會(huì)被執(zhí)行的。

其實(shí)寫這篇東西的另一個(gè)目的也是想說:每一件看似簡單的事情背后,如果你花一些時(shí)間去思考和研究,也許就會(huì)發(fā)現(xiàn)很多更深刻的意義和結(jié)果。這并不是要我們變成一個(gè)多疑的偏執(zhí)狂,而是我覺得思索和提問的習(xí)慣是有益的。對(duì)于一個(gè)看似簡單的道理,我們能不能提出讓自己信服的佐證來,我們是否有一種直覺,告訴自己:Iamwonderingifthereismoretoit。事實(shí)上,這個(gè)世界上的偏執(zhí)狂是少數(shù),多的,是人云亦云的大眾。

【前幾周熱點(diǎn)周報(bào)】

  1. 開發(fā)熱點(diǎn)周報(bào):ASP.NET與PHP性能大戰(zhàn) 開源界風(fēng)波再起
  2. 開發(fā)熱點(diǎn)周報(bào):ASP.NET MVC 2發(fā)布 STM淘汰線程鎖
  3. 開發(fā)熱點(diǎn)周報(bào):微軟示好Linux Ruby+Rails小更新
  4. 開發(fā)熱點(diǎn)周報(bào):甲骨文補(bǔ)丁日 Azure價(jià)格確定
  5. 開發(fā)熱點(diǎn)周報(bào):Silverlight 3發(fā)布 XHTML 2夭折
責(zé)任編輯:彭凡 來源: IT168
相關(guān)推薦

2019-12-18 15:11:42

數(shù)組集合數(shù)據(jù)

2020-03-13 14:45:14

Java枚舉代碼

2015-03-18 14:12:50

2017-09-07 16:32:05

華為

2009-04-13 09:35:50

SaaS云計(jì)算缺陷

2014-12-18 10:16:00

Java

2017-03-02 13:56:45

Facebook廣告歸因

2016-08-16 13:30:49

LinuxCachetmpfs

2010-02-07 13:45:12

Android操作系統(tǒng)

2010-01-26 09:24:53

C++語言

2018-09-30 09:36:58

CTO代碼程序員

2019-02-13 23:03:06

IE瀏覽器微軟

2012-04-16 10:15:13

JQuery插件開發(fā)

2010-01-15 16:45:35

C++語言

2010-03-02 10:26:32

Android系統(tǒng)平臺(tái)

2019-08-27 08:24:17

簡歷技能工作

2020-04-03 14:25:55

diff Meld工具

2021-01-11 08:03:30

阿里中臺(tái)項(xiàng)目

2023-04-21 10:33:42

2021-01-20 10:40:16

緩存固態(tài)硬盤SSD
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)