繼續提案

lua-users home
wiki

新增一個 continue 敘述,用於終止一個 whilerepeatfor 迴圈目前的迭代,略過下一個迴圈迭代條件的評估。就像 returnbreak 敘述一樣,continue 只能寫在一個區塊的最後一個敘述。

動機

想要知道官方為何不將 continue 納入 Lua 的動機,請參閱[1]

優點

缺點

討論

世界上幾乎所有其他語言都有這種等同的功能。當然,您可以重新調整程式碼結構以解決這個限制,但這並不好。反對在迴圈中使用「continue」的論點也可以同樣用於反對「return」。當然,有了這種限制,您可以將程式碼結構調整成一連串的 if/then/else,但這非常令人困擾。能夠從程式碼區塊的「中間」跳出,就如同能夠在迴圈中「繼續」,是一種便利,而且不會損害可讀性。因此,這是我的請願:「繼續」這個功能。如果很容易就能實作,為什麼不呢?--DanHollis?

return不太像continue,因為除了終止函式外,它至少還有兩個額外的目的:(a) 識別函式傳回的值;(b) 使編譯器更容易識別尾呼叫。--RenatoMaia?

我不明白為什麼 Lua 沒有「continue」。在 C(和其他語言)中,它的使用頻率與「break」一樣高。它的使用具有好處:當需要時,它不需要我們想辦法模擬它(在演算法中)。我在 Lua 下一個版本中支持它。-- JulioFernandez

我懷疑「continue」的實際使用頻率是否真的有和「break」一樣高。K&R 實際上表示其使用頻率較低。--JohnCowan?

身為一位 C 編碼器,我非常習慣使用「continue」,因為它通常能讓迴圈乾淨,並省去另一個不需要的意圖層級。此外,它容易閱讀、理解,因此在長期上容易於維護,而這裡提出的解決方法依我拙見則不然。順帶一提,linux 核心使用「break」一詞 106207 次,使用「continue」一詞 14393 次。因此是 10%(但包括所有 switch 陳述式)。但為何要完全捨棄使用率達 10% 的東西?畢竟,對於 LUA 的生手,這與二進位運算子遺失是重要的資訊(而且奇怪的是,為什麼全域變數預設為 local 而非反之,並且使用關鍵字表示全域使用。但我猜測另一方面現在要修正已經太晚了。)--~~~~

我剛剛在 LuaPowerPatches 中審核了 Lua 5.1.3 的修補程式,並附上一小段測試套件來證明其運作無誤。-- WolfgangOertl

我支持這項提議。對我來說,主要的優點是「continue」清楚且正確地表達了演算法及編寫人員的意圖。程式碼較不複雜或較短只是一個很好的副作用。一個問題在於「continue」與「break」都很含糊(退出目前疊代或整體重複?)基於這個原因,我認為「next」對於建議的語意來說好上許多。「next」本身較為精準,而「next」+「break」消除了「break」的含糊性。(「next」+「exit」甚至可能更好,但它可能會與「os.exit」的語意衝突。)-- Denis

在標準 Lua 中模擬 continue

使用 if

你通常能夠透過變更下列程式碼範本來模擬 continue

while invariant do
  <START BLOCK>
  if condition then
    <MIDDLE BLOCK>
    continue
    -- nothing is allowed here and there is
    -- no sense in adding an 'else' here
  end
  <FINISH BLOCK>
end

while invariant do
  <START BLOCK>
  if condition then
    <MIDDLE BLOCK>
  else
    <FINISH BLOCK>
  end
  -- here you have the chance to add a
  -- finalization code that is always executed
end

使用錯誤

你可以使用 lua 錯誤 :),程式碼可能如下所示

while cond do
  local b, err = pcall(function()
    ...some code...
    error("continue") -- the 'continue' equivalent :
    ...some code...
  end)
  -- if there is another error :
  if not b and err ~= "continue" then error(err) end
end

不幸的是,在出現錯誤時,你會失去堆疊回溯 ... 你可以使用 xpcall 和 debug.traceback() 來保留它 :) 我也會比較傾向於有一個 continue 陳述式 :)

--Mildred

使用 break

在純 Lua 中模擬「continue」很簡單(雖然有點囉嗦)。--GregLudwig?

以下是一個用於在 Lua 中模擬 continue 陳述式的簡單慣用語法。基本概念是使用一個區域變數 continue,以及在 repeat 一次區塊中的 break 陳述式。

我們想要在以下範例中實作 continue

for line in io.lines() do

   -- start BODY
   if string.find(line,"c") then continue end

   if string.find(line,"b") then break end

   print("-->",line)
   -- end BODY

end

為達成此目的,請將 BODY 取代為

local continue
repeat
   -- start BODY
   'BODY' replacing 'continue' with 'continue=true; break'
   -- end BODY
   continue=true
until 1
if not continue then break end

因此範例就會變成

for line in io.lines() do

   local continue
   repeat
      -- start BODY
      if string.find(line,"c") then continue=true; break end

      if string.find(line,"b") then break end

      print("-->",line)
      -- end BODY

      continue=true
   until 1
   if not continue then break end

end

為了 continue 功能(也就是說總是繼續),可以不縮排以下內容

for line in io.lines() do repeat
    if string.find(line,"c") then break end
    print("-->",line)
until 1 end

Lua 5.2.0beta-rc1

在 Lua 5.2.0beta-rc1 中,你可以透過使用 GotoStatement 來撰寫上述範例,如下所示

for line in io.lines() do
   if string.find(line,"c") then goto continue end
   if string.find(line,"b") then break end
   print("-->",line)
   @continue:
end

修補程式

請參閱

另請參閱


近期變更 · 偏好設定
編輯 · 歷史
上次編輯時間為 2012 年 3 月 27 日下午 2:32 GMT (diff)