為什麼Lua不支持大多數編程語言都有的continue,卻非得支持一般情況下用得很少的 repeat until ?
Lua 不支持 continue 的原因在於 compiler 的實現。Lua 的 compiler 是一個 single-pass compiler。從詞法分析到代碼生成均在一個 pass 中完成,這樣的問題在於,不能做複雜的 block 分析。就是說,要求 Lua compiler 從一個 block 中的任意位置尋找到其 end,是很困難的。
---- 以下是舊答案 ----
Lua 對其 VM 的資源消耗很重視。能少一個操作就盡量少一個。
另一個例子是 for。Lua 在 1.0 之後的七年里沒有 for,因為 for 只不過又是另一個控制操作而已,直到他們實現了 closure 並且發現了用 generator function 來讓 for 起到更廣泛的作用。現在,沒人能發現 continue 能有什麼更大的作用。我其實也想不明白這一點。
增加對continue的支持,並不會增加新的Lua VM Opcode種類,只需要復用原來的Opcode組合一下就行了。但是對使用者來說,有了continue卻可以讓寫出來的Lua代碼更好看,不用用其他醜陋的方式替換。
試想看,在一個循環語句中,可以使用條件然後continue過濾掉一些不必要的情況,在過濾完畢之後再進行正常的處理,比如:for statement:
if not exp1then continueend
if not exp2 then continue end do_something_hereend
沒有了continue只能這麼寫:for statement: if exp1 and exp2 thendo_something_here
endend可以看到,如果有exp3,exp4.。。expn的時候,這個代碼會很醜陋的。關於沒有 continue,Roberto 在郵件列表裡解釋過[1]:
[...] Our main concern with "continue" is that there are several other control structures that (in our view) are more or less as important as "continue" and may even replace it. (E.g., break with labels [as in Java] or even a more generic goto.) "continue" does not seem more special than other control-structure mechanisms, except that it is present in more languages. (Perl actually has two "continue"statements, "next" and "redo". Both are useful.)
Continue 出現的場合均可以用 if then 替代,或者在 for 循環中套一個 repeat until 循環[2],雖然丑是比較丑。Lua 5.2.0 beta 中出現的 goto 也可以用來替代 continue。更多討論詳見[3]。
至於 repeat until 其實不算「非得支持」,算是順手支持的吧,實現起來很簡單[4]。
[1] http://lua-users.org/lists/lua-l/2008-02/msg01183.html
[2] http://lua-users.org/lists/lua-l/2006-12/msg00440.html
[3] http://lua-users.org/wiki/ContinueProposal
[4] http://www.lua.org/source/5.1/lparser.c.html,"repeatstat" 與 「whilestat」。
實現continue並不難,break和continue的唯一差別在於,break跳轉到出口,continue跳轉到入口,所以能實現break,就能實現continue。
可能是C語言寫習慣了,好想加分號結尾,好想用()與{},好想加switch.
推薦閱讀:
※為什麼很多編程語言用 end 作為區塊結束符,而放棄花括弧?
※unity中lua的開發工具?
※學習哪些 Functional programming language 能夠拓寬眼界,學到和其他編程範式明顯不一樣的東西?
※Lua 為什麼在遊戲編程領域被廣泛運用?