继续提案

lua-users home
wiki

添加一个continue语句,用于终止当前whilerepeatfor循环的迭代,跳过到下一个循环迭代的条件评估。就像returnbreak语句一样,continue只能作为块的最后一个语句编写。

动机

有关 Lua 不包含continue的官方动机,请参阅 [1]

优点

缺点

讨论

几乎所有其他语言都具有等效的功能。当然,您可以重新构建代码以绕过此限制,但这并不理想。反对循环中使用“continue”的论点同样适用于“return”。当然,有了这样的限制,您可以将代码重新构建成 if/then/else 塔,但这非常烦人。能够从代码块中间“return”就像能够在循环中“continue”一样——这是一种便利,不会损害可读性。所以这是我对“continue”的呼吁。如果它易于实现,为什么不呢?--DanHollis?

returncontinue并不完全相同,因为它除了终止函数外,至少还有两个其他用途:(a)标识函数返回的值;以及(b)使编译器更容易识别尾调用。--RenatoMaia?

我不理解 Lua 中缺少“continue”的原因。这在 C(和其他语言)中与“break”一样常用。它的使用有益:它不需要我们在需要时寻找技巧来模拟它(在我们的算法中)。我投票支持它在 Lua 的下一个版本中出现。-- JulioFernandez

我怀疑“continue”是否真的像“break”一样常用。K&R 实际上说它使用频率较低。--JohnCowan?

作为 C 语言程序员,我非常习惯使用 "continue" - 因为它通常可以保持循环的整洁,并避免不必要的缩进层级。此外,它易于阅读、理解,因此在长期维护中也更易于维护,而这里提出的解决方法在我看来并不易于维护。顺便说一下,Linux 内核使用了 106207 次 "break" 和 14393 次 "continue"。所以大约占 10%(但包括所有 switch 语句)。但为什么完全抛弃一个使用率高达 10% 的东西呢?毕竟,作为 Lua 新手,这和缺少二元运算符是我遇到的重大问题(我很好奇为什么全局变量是默认的,而不是相反,局部变量是默认的,而全局变量需要使用关键字。但我认为,另一方面,现在修复已经太晚了。)--~~~~

我刚刚修改了 Lua 5.1.3 的补丁(在 LuaPowerPatches 中),并附带了一个小型测试套件来证明它的有效性。-- 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 语句的简单习惯用法。基本思路是在一个 repeat-once 块中使用一个局部 continue 变量和 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 (差异)