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

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

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

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

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

流程圖如下(Java 示例):

  1. // 打印小于 20 的數(shù)字 
  2. public class Test { 
  3.    public static void main(String[] args){ 
  4.       int x = 10; 
  5.       do { 
  6.          System.out.print("value of x : " + x ); 
  7.          x++; 
  8.          System.out.print("\n"); 
  9.       } while(x < 20); 
  10.    } 

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

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

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

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

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

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

除了這一特點(diǎn),這種結(jié)構(gòu)最大的應(yī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é)果。

  1. do { 
  2.   // 執(zhí)行步驟 1  
  3.   if (條件1失敗) { 
  4.     break; 
  5.   } 
  6.   // 執(zhí)行步驟 2  
  7.   if (條件2失敗) { 
  8.     break; 
  9.   } 
  10.   // 執(zhí)行步驟 3  
  11.   if (條件3失敗) { 
  12.     break; 
  13.   } 
  14. } while(0); 
  15. // 執(zhí)行步驟 4 
  16. // 執(zhí)行步驟 5 

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

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

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

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

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

  1. do: 
  2.     pass 
  3. while False 

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

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

PEP-315 Enhanced While Loop

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

  1. do: 
  2.     <setup code> 
  3. while <condition>: 
  4.     <loop body> 

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

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

  1. while_stmt : ["do" ":" suite] 
  2.             "while" expression ":" suite 
  3.             ["else" ":" suite] 

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

也就是說,在保持原 while 循環(huán)語法不變的情況下,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)鍵字和語法,僅使用現(xiàn)有語法就能很好地實(shí)現(xiàn)同樣的功能:

  1. while True
  2.     <setup code> 
  3.     if not <condition>: 
  4.         break 
  5.     <loop body> 

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.

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

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

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

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

作者簡介 ▽

豌豆花下貓,生于廣東畢業(yè)于武大,現(xiàn)為蘇漂程序員,有一些極客思維,也有一些人文情懷,有一些溫度,還有一些態(tài)度。

本文轉(zhuǎn)載自微信公眾號(hào)「Python貓」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Python貓公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: Python貓
相關(guān)推薦

2022-10-28 07:38:06

Javawhile循環(huán)

2024-02-26 12:13:32

C++開發(fā)編程

2021-11-19 09:49:00

CC++語法糖

2020-07-23 08:18:27

C語言執(zhí)行循環(huán)體條件

2024-12-10 08:41:12

語句if卡死

2019-03-11 08:36:11

Python代碼Flask

2020-04-01 17:50:02

Python編程語言

2021-04-13 11:15:54

網(wǎng)絡(luò)安全C語言循環(huán)結(jié)構(gòu)

2020-12-11 05:57:01

Python循環(huán)語句代碼

2021-12-09 23:20:31

Python循環(huán)語句

2024-12-19 16:00:00

Pythonwhile 循環(huán)

2021-03-24 13:17:41

編程循環(huán)語句Java

2023-04-20 13:59:01

Pythonwhile循環(huán)的

2021-06-22 10:12:37

JavaScript 前端While 循環(huán)

2021-08-13 15:09:47

JavaScriptWhile循環(huán)

2024-04-24 12:45:06

index性能數(shù)組

2010-09-08 17:00:22

SQLWHILE循環(huán)

2023-11-06 13:04:59

Python日志庫

2011-06-16 15:29:22

2024-10-25 14:39:26

BigDecimal精度數(shù)值
點(diǎn)贊
收藏

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