<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python 為什么不設(shè)計(jì) do-while 循環(huán)結(jié)構(gòu)?

          共 383字,需瀏覽 1分鐘

           ·

          2022-04-20 19:43


          在某些編程語(yǔ)言中,例如 C/C++、C#、PHP、Java、JavaScript 等等,do-while 是一種基本的循環(huán)結(jié)構(gòu)。


          它的核心語(yǔ)義是:先執(zhí)行一遍循環(huán)體代碼,然后執(zhí)行一遍條件語(yǔ)句,若條件語(yǔ)句判斷為真,則繼續(xù)執(zhí)行循環(huán)體代碼,并再次執(zhí)行條件語(yǔ)句;直到條件語(yǔ)句判斷為假,則跳出循環(huán)結(jié)構(gòu)。

          流程圖如下(Java 示例):

          //?打印小于?20?的數(shù)字
          public?class?Test?{
          ???public?static?void?main(String[]?args){
          ??????int?x?=?10;
          ??????do?{
          ?????????System.out.print("value?of?x?:?"?+?x?);
          ?????????x++;
          ?????????System.out.print("\n");
          ??????}?while(x?20);
          ???}
          }

          Python 并不支持 do-while 結(jié)構(gòu),“do”并不是一個(gè)有效的關(guān)鍵字。

          那么,為什么 Python 不提供這種語(yǔ)法結(jié)構(gòu)呢,這種現(xiàn)狀的背后有何種設(shè)計(jì)考量因素呢?

          在回答這個(gè)問題之前,讓我們?cè)僮屑?xì)思考一下 do-while 語(yǔ)法可以解決什么問題,看看使用這種結(jié)構(gòu)能帶來什么好處?

          最顯而易見的好處是:do-while 語(yǔ)法保證了會(huì)先執(zhí)行一遍循環(huán)體代碼。

          它的使用場(chǎng)景也許不多,但是,跟普通的 while 循環(huán)或者 for 循環(huán)語(yǔ)法的“條件前置”思想不同,它體現(xiàn)的是一種“條件后置”的編程邏輯,也是一種控制循環(huán)的常見方式。

          它們的關(guān)系似乎有點(diǎn)像 C/C++ 這些語(yǔ)言中的i++++i操作的區(qū)別,在某些特殊場(chǎng)合中,也許會(huì)更為高效。

          除了這一特點(diǎn),這種結(jié)構(gòu)最大的應(yīng)用場(chǎng)景其實(shí)是在 C/C++ 中特殊的do {...} while (0) 用法。這在很多開源項(xiàng)目的源碼中都能找到蹤跡,例如 Linux、Redis 以及 CPython 解釋器,等等。

          這里面的數(shù)字 0 表示布爾值 False,意味著循環(huán)只會(huì)執(zhí)行一遍,然后就跳出。

          這樣的寫法是不是很詭異?所謂“循環(huán)”,一般就意味著程序體會(huì)被反復(fù)執(zhí)行多次,但是,do {...} while (0) 卻偏偏只需要它執(zhí)行一遍,這初看起來是有點(diǎn)多余啊。

          這種寫法主要用在宏函數(shù)的定義中,可以解決宏代碼塊的編譯問題,使代碼按照我們的意圖而合理分塊。

          另外,do {...} while (0) 結(jié)合 break 使用,還可以實(shí)現(xiàn)很優(yōu)雅的跳轉(zhuǎn)控制效果。

          在下面的示例中,步驟 1、4 和 5 要求必須執(zhí)行,而步驟 2 取決于步驟 1 的執(zhí)行結(jié)果,步驟 3 則取決于步驟 2 的執(zhí)行結(jié)果。

          do?{
          ??//?執(zhí)行步驟?1?
          ??if?(條件1失敗)?{
          ????break;
          ??}
          ??//?執(zhí)行步驟?2?
          ??if?(條件2失敗)?{
          ????break;
          ??}
          ??//?執(zhí)行步驟?3?
          ??if?(條件3失敗)?{
          ????break;
          ??}
          }?while(0);
          //?執(zhí)行步驟?4
          //?執(zhí)行步驟?5

          在這種場(chǎng)景中,我們確實(shí)只需要按照順序執(zhí)行一遍。do-while 結(jié)構(gòu)很清晰,避免造成多層條件嵌套或者設(shè)置諸多額外標(biāo)記的局面。

          最后還有一點(diǎn),在匯編層面,do-while 比 while 更接近匯編語(yǔ)言的邏輯,可以節(jié)省使用指令,在過去的低內(nèi)存時(shí)代,算得上是一種優(yōu)化寫法。

          分析完 do-while 的好處后,讓我們回到主題:Python 為什么不需要設(shè)計(jì) do-while 循環(huán)語(yǔ)法呢?

          首先,Python 離底層應(yīng)用編程太遠(yuǎn)了,就不用考慮匯編指令的優(yōu)化了,同時(shí),它也不涉及宏的使用。

          至于“條件前置”和“條件后置”的區(qū)別,其實(shí)并沒有太大影響,而且,由于 Python 使用簡(jiǎn)潔優(yōu)雅的縮進(jìn)加冒號(hào)語(yǔ)法來劃分代碼塊,導(dǎo)致直譯過來的 do-while 語(yǔ)法看起來會(huì)很怪異(注意,直譯的 while 的條件后沒有其它內(nèi)容):

          do:
          ????pass
          while?False

          想要引入新的語(yǔ)法特性,必然要遵守既定的風(fēng)格習(xí)慣。其它語(yǔ)言的 do-while 結(jié)構(gòu)直譯成 Python 的話,肯定不合適。

          事實(shí)上,在 2003 年時(shí),有一個(gè) PEP 提議給 Python 加上 do-while 語(yǔ)法支持:

          PEP-315 Enhanced While Loop

          該 PEP 提議增加一個(gè)可選的 do 子句,支持將 while 循環(huán)擴(kuò)展成這樣子:

          do:
          ????
          while?:
          ????

          這不是簡(jiǎn)單地從其它語(yǔ)言翻譯成 Python,它的 while 語(yǔ)句后保留了 Python 的縮進(jìn)用法,并不會(huì)造成直譯形式的突兀結(jié)果。

          加上 while 循環(huán)本身已支持的可選的 else 子句,因此,while 完整的語(yǔ)法結(jié)構(gòu)是這樣的:

          while_stmt?:?["do"?":"?suite]
          ????????????"while"?expression?":"?suite
          ????????????["else"?":"?suite]

          (PS.在本系列的下一篇文章,我們將解釋為什么 Python 要支持 while-else 語(yǔ)法)

          也就是說,在保持原 while 循環(huán)語(yǔ)法不變的情況下,PEP-315 提議支持在 while 前面使用一個(gè)可選的 do 子句。

          do 子句只會(huì)執(zhí)行一遍,當(dāng)它里面出現(xiàn) break 時(shí),則跳出整個(gè) do-while 循環(huán);當(dāng) do 子句中出現(xiàn) continue 時(shí),則跳出 do 子句,進(jìn)到 while 的條件判斷中。

          有了 do 子句后,很容易就能實(shí)現(xiàn) do {...} while (0) 的跳轉(zhuǎn)控制效果。

          但是,這個(gè) PEP 遭到了一些核心開發(fā)者的反對(duì)。

          反對(duì)的理由是,不需要引入新的關(guān)鍵字和語(yǔ)法,僅使用現(xiàn)有語(yǔ)法就能很好地實(shí)現(xiàn)同樣的功能:

          while?True:
          ????
          ????if?not?:
          ????????break
          ????

          Python 之父 Guido van Rossum 也持反對(duì)意見,他的原話是:

          Guido的回復(fù)

          Please reject the PEP. More variations along these lines won't make the language more elegant or easier to learn. They'd just save a few hasty folks some typing while making others who have to read/maintain their code wonder what it means.

          簡(jiǎn)單翻譯一下,這種 do-while 語(yǔ)法并不會(huì)使 Python 更優(yōu)雅好用,反而會(huì)產(chǎn)生閱讀/維護(hù)代碼的理解負(fù)擔(dān)。

          就個(gè)人的感覺而言,我也不贊成引入 PEP-315 那種可選的 do-while 語(yǔ)法,雖然它比固定形式的 do-while 結(jié)構(gòu)更為靈活和優(yōu)雅一點(diǎn)。

          最后稍微總結(jié)一下,do-while 作為一種常見的循環(huán)結(jié)構(gòu),在其它語(yǔ)言中有所發(fā)揮,它甚至還發(fā)展出了do {...} while (0) 的典型用法,但是,do-while 能夠解決的幾個(gè)問題要么在 Python 中并不存在(宏定義、匯編指令),要么就是已經(jīng)有更為合適而低成本的實(shí)現(xiàn)(跳轉(zhuǎn)控制)。

          看完這篇文章,你是否還有其它補(bǔ)充的內(nèi)容呢?歡迎交流討論。

          這是我開發(fā)的機(jī)器人公眾號(hào)小號(hào),目前增加了天氣查詢,955公司名單,關(guān)注時(shí)間查詢;后面還會(huì)增加圖片功能和每日送書抽獎(jiǎng)送書活動(dòng),以及調(diào)戲功能,歡迎來體驗(yàn),捧場(chǎng)。


          一個(gè)機(jī)器人公眾號(hào)已經(jīng)上線,歡迎調(diào)戲




          推薦閱讀:

          入門:?最全的零基礎(chǔ)學(xué)Python的問題? |?零基礎(chǔ)學(xué)了8個(gè)月的Python??|?實(shí)戰(zhàn)項(xiàng)目?|學(xué)Python就是這條捷徑


          干貨:爬取豆瓣短評(píng),電影《后來的我們》?|?38年NBA最佳球員分析?|? ?從萬(wàn)眾期待到口碑撲街!唐探3令人失望? |?笑看新倚天屠龍記?|?燈謎答題王?|用Python做個(gè)海量小姐姐素描圖?|碟中諜這么火,我用機(jī)器學(xué)習(xí)做個(gè)迷你推薦系統(tǒng)電影


          趣味:彈球游戲? |?九宮格? |?漂亮的花?|?兩百行Python《天天酷跑》游戲!


          AI:?會(huì)做詩(shī)的機(jī)器人?|?給圖片上色?|?預(yù)測(cè)收入?|?碟中諜這么火,我用機(jī)器學(xué)習(xí)做個(gè)迷你推薦系統(tǒng)電影


          小工具:?Pdf轉(zhuǎn)Word,輕松搞定表格和水印!?|?一鍵把html網(wǎng)頁(yè)保存為pdf!|??再見PDF提取收費(fèi)!?|?用90行代碼打造最強(qiáng)PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換?|?制作一款釘釘?shù)蛢r(jià)機(jī)票提示器!?|60行代碼做了一個(gè)語(yǔ)音壁紙切換器天天看小姐姐!



          年度爆款文案


          點(diǎn)閱讀原文,看B站我的視頻!

          瀏覽 27
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国家一级黄色片 | 性爱大全无码 | 麻豆国产免费 | 余亚洲成人AV片 | 国产精品爽爽久久久久 |