2010-07-10 94 views
18

幾天前,我開始了一個快速開源項目,當一些隊友看着svn上的代碼時,其中一個人告訴我在for循環中使用break聲明被認爲是有害的,不應該這樣做。使用「break」打破「for」循環被認爲是有害的?

但他補充說,我會在Linux內核源代碼的for循環內發現break語句的幾個例子,但那只是因爲只有Linus Torvalds和Chuck Norris被允許使用它而沒有其他人。

您認爲如何?在for循環中使用break時,我看不到任何問題。在我看來,使用布爾變量或類似的東西來模擬break的行爲會增加很多不必要的開銷,並且使代碼更簡單。

此外,沒有空間與goto進行比較,因爲break不能任意改變程序從一個點到另一個點的位置,goto

+2

重複的問題:http://stackoverflow.com/questions/216359/break-statements-in-the-real-world 而另一個,關閉作爲重複:http://stackoverflow.com/questions/616339/ is-break-evil – 2010-07-10 01:35:12

+0

雖然我認爲'continue'被認爲是「有害的」,但在與「goto」相同的聯盟中(兩者都可以是有用的,但都可以隱藏代碼)。個人而言,「休息」對我來說看起來很好。 – 2010-07-10 01:44:04

+2

我經常使用'break',並且經常使用'continue'。我認爲 - 同樣的事情適用於多個存在,Delphi' while'語句等等 - 在大多數情況下,當有人說「不使用X構造」時,他/她是不太習慣於編寫複雜的算法和/或他/她對手邊語言不太熟練。因爲,如果一個人對手邊的語言非常有經驗,那麼就知道如何使用這個構造,如果人們經常編寫複雜的算法,那麼人們會喜歡所有這些構造。 – 2010-07-10 19:44:15

回答

42

我看到使用中斷沒有問題。總會有一些情況要停止處理一個循環,並且使用一個break;變得更有意義(並且使它更易讀!),而不是將循環計數器設置爲一個值,以使循環在下一次迭代時停止。

+7

我看到使用goto沒有問題。總會有一些情況你想停止處理一個非常嵌套的循環,並使用goto;比使用布爾值告訴你什麼時候離開循環更有意義(並使其更易讀)。 – 2010-07-26 13:36:56

39

強制性:

XKCD Goto

的一點是,你不應該回避它純粹是不好的做法的理由(或伶盜龍屬),但考慮到對個別情況。

這是關於清晰度。正如你所說,你永遠不必使用它,但在某些情況下,它提高了可讀性。當循環通常正常結束時,這很有用,但在極少數情況下,您必須紓困。通常(或總是)中斷的循環更像是一種代碼異味(但仍然適用)。

+11

+1爲此漫畫提供了一個很好的答案。我記得看到一個嚴重問題的答案就是這個漫畫,沒有別的,呃。 – Maulrus 2010-07-10 01:38:08

1

我認爲這取決於上下文。雖然在某些情況下它可能是'糟糕的'編碼風格,但我不能想到這將是有害的情況。

事實上,在某些情況下,我會推薦它。例如,如果您使用線性搜索, 任何情況(除非最糟糕的情況), break會提高您的速度。 我認爲,當你發現你的針頭完全可以接受時,打破循環,而且它比用循環變量(可能不僅僅用於循環,取決於你的程序)更易於閱讀或者將循環體包裝在if塊中。 (和其他選項,其中包含continueif,結合了最嚴重的兩個世界:在if塊包裝循環邏輯,而被人們喜歡你的朋友誰不喜歡break抨擊窮人的編碼風格)

+0

你不應該建議在表演的基礎上休息。編譯器通常可以優化狀態變量。 – Artelius 2010-07-10 01:33:51

+0

公平點。我試圖做的一點是,例如,如果我對大量元素進行線性搜索,並且在索引2處找到了我期望的內容,我寧願停止查找,而不是繼續循環我知道我不想要的其餘元素。另一方面,如果我知道我會有大量的元素,反正我可能不會去進行線性搜索。 – 2010-07-10 19:25:24

20

使用break不僅沒有問題,我認爲任何人認爲它被認爲是有害的是完全錯誤的。

break是一種用於中止循環的語言功能 - 您可以使用goto,但是您會在下面引發(適當的)XKCD漫畫的憤怒。您可以在條件下使用標誌,但會妨礙可讀性。 break不僅是最簡單的,而且也是多次跳出循環的最清晰的方式。按照它的意圖使用它。


編輯:要獲取更大的圖片瀏覽:當你寫代碼,指導原則,以「我應該用語言特性X或Y」應爲「哪一種方式將導致更多優雅的代碼「?在代碼中,優雅是一門藝術,但我認爲它是可讀性和算法(讀取:不是微型優化)效率之間的良好平衡。可讀性將取決於長度,代碼的複雜程度等。單線boost :: bind可能比3線循環難於理解。

如果語言功能可以幫助您編寫在完成工作時更易於理解的代碼,然後使用它。這適用於breakgoto,C++異常等。不要盲目地遵循「X is(邪惡|認爲有害)」 - 每次應用常識和邏輯。

2

有一個範例,任何循環只應該有一個出口點(與函數相同,只應該有一個返回點)。這與可讀性有關。太多退出點可能會使代碼非常難以理解。此外,如果您想要進行代碼驗證(即數學證明代碼是否正確),這一點非常重要。

但是,指導方針通常有幫助,但並不嚴格。有可能的情況下休息比不使用它好。因此,一個人應該務實這一點,但理解這些原則的原因,以創建良好的代碼。

1

增加你的循環計數器而不是使用break也意味着你完成了循環的當前迭代,這可能是也可能不是所希望的。
當然,你可以包裝它的其餘部分在if條款,然後再做一次,當你意識到你需要檢查是否要停止循環多次,你很快就會明白爲什麼人們使用break;

11

break不僅沒有問題,而且break不足,也是OK to use goto。不要害怕多次回報。

以上所有僅適用於使代碼更容易理解*的情況。

*如果您PHB允許它...

1

我建議這個算法,如果你使用一個給定的技術考慮。

  • 如果它被認爲是好的做法
    • 使用它。
  • 如果好的做法:
    • 只使用它,如果你判斷它是最好的長期解決方案。
  • 如果認爲邪惡
    • 只使用它,如果你判斷它是最好的長期解決方案,你在你的判斷非常有信心。注意:被認爲是邪惡的東西往往具有迷人的吸引力。

我會分類break;爲 「不是好的做法。」當它使代碼更易讀,減少錯誤的機會,不會使調試複雜化等等時使用它。

+0

我一直在使用break ... – 2010-07-10 19:38:09

7

我認爲你的伴侶瘋了。 break是完全可以接受的,完全可讀且完美可維護的。期。