這個本來是之前在微博上有個同學(xué)說他經(jīng)常用來面試別人,大概是說,對于如下代碼,你覺得會輸出啥:
$a = true; if ($a) { echo “true”; } else label: { echo “false”; }
當時覺得有點偏,沒想寫,今天中午又有人問我,我想那就介紹下這個原因吧.
首先,上面的代碼輸出truefalse, 如果你知道原因,那就不用繼續(xù)往下看了,如果不知道,那么:
這塊讓人比較迷惑的原因可能是因為,我們會很直觀的認為:
label : { statement; }
應(yīng)該是一個整體, 就好比類似:
if ($a) { } else switch($a) { }
或者:
if ($a) { } else do { } while (!$a);
因為在PHP的語法設(shè)計中,if else本質(zhì)上是:
if_stmt: if_stmt_without_else T_ELSE statement
也就是說,else后面可以接一切statement,如果條件不成立,執(zhí)行流就跳到else后面的statement,而while, switch都可以歸約為statement。
但label這塊稍微有點特別(可以說是一個設(shè)計違反直覺的”缺陷”吧), 在zend_language_parser.y中:
statement: ... | T_DO statement T_WHILE '(' expr ')' ';' {...} | T_SWITCH '(' expr ')' switch_case_list {...} | T_STRING ‘:’ { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }
大家可以看到, do while, switch 都會聯(lián)合他們的body歸約為statement(語句),但標簽(label)有點不同,”label :”本身會規(guī)約為一條statement, 這就導(dǎo)致了這個看起來比較迷惑的問題的出現(xiàn),他本質(zhì)上就變成了:
$a = true; if ($a) { echo "true"; } else { label: ; //單獨的一條語句 } echo "false";
最后多說一句,我忘了之前在那看到的,說是這個世界上本無elseif,有的只不過是else (if statement),本質(zhì)上其實就跟這個意思是一樣的。 就是,else后面可以接語句(statement)。
善用這個結(jié)合switch, for, do while等,有的時候可以讓我們的代碼更精簡。
比如,我們要遍歷處理一個數(shù)組,當數(shù)組的長度為零的時候,要做點其他事,那很多人可能會這么寫:
if (count($array)) { for ($i = 0; $i < count($array); $i++) { } } else { //數(shù)組為空的邏輯 }
但你也可以寫成:
if (count($array) == 0) { //數(shù)組為空的邏輯 } else for ($i = 0; $i < count($array); $i++) { }
至于這倆中寫法孰好孰壞, 那就是蘿卜白菜了。
最后,大家如果在實際中遇到類似讓大家覺得迷惑的問題,可以留言,也許以后也可以單獨成文。
本文標題:一個關(guān)于ifelse容易迷惑的問題!
文章路徑:http://aaarwkj.com/article34/chscpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、用戶體驗、網(wǎng)站設(shè)計、外貿(mào)建站、虛擬主機、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)