Why does Lua have no “continue” statement?

后端 未结 11 1681
无人及你
无人及你 2020-12-07 13:23

I have been dealing a lot with Lua in the past few months, and I really like most of the features but I\'m still missing something among those:

  • Why is there no
相关标签:
11条回答
  • 2020-12-07 13:57

    Straight from the designer of Lua himself:

    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.)

    0 讨论(0)
  • 2020-12-07 13:58

    In Lua 5.2 the best workaround is to use goto:

    -- prints odd numbers in [|1,10|]
    for i=1,10 do
      if i % 2 == 0 then goto continue end
      print(i)
      ::continue::
    end
    

    This is supported in LuaJIT since version 2.0.1

    0 讨论(0)
  • Lua is lightweight scripting language which want to smaller as possible. For example, many unary operation such as pre/post increment is not available

    Instead of continue, you can use goto like

    arr = {1,2,3,45,6,7,8}
    for key,val in ipairs(arr) do
      if val > 6 then
         goto skip_to_next
      end
         # perform some calculation
      ::skip_to_next::
    end
    
    0 讨论(0)
  • 2020-12-07 14:03

    You can wrap loop body in additional repeat until true and then use do break end inside for effect of continue. Naturally, you'll need to set up additional flags if you also intend to really break out of loop as well.

    This will loop 5 times, printing 1, 2, and 3 each time.

    for idx = 1, 5 do
        repeat
            print(1)
            print(2)
            print(3)
            do break end -- goes to next iteration of for
            print(4)
            print(5)
        until true
    end
    

    This construction even translates to literal one opcode JMP in Lua bytecode!

    $ luac -l continue.lua 
    
    main <continue.lua:0,0> (22 instructions, 88 bytes at 0x23c9530)
    0+ params, 6 slots, 0 upvalues, 4 locals, 6 constants, 0 functions
        1   [1] LOADK       0 -1    ; 1
        2   [1] LOADK       1 -2    ; 3
        3   [1] LOADK       2 -1    ; 1
        4   [1] FORPREP     0 16    ; to 21
        5   [3] GETGLOBAL   4 -3    ; print
        6   [3] LOADK       5 -1    ; 1
        7   [3] CALL        4 2 1
        8   [4] GETGLOBAL   4 -3    ; print
        9   [4] LOADK       5 -4    ; 2
        10  [4] CALL        4 2 1
        11  [5] GETGLOBAL   4 -3    ; print
        12  [5] LOADK       5 -2    ; 3
        13  [5] CALL        4 2 1
        14  [6] JMP         6   ; to 21 -- Here it is! If you remove do break end from code, result will only differ by this single line.
        15  [7] GETGLOBAL   4 -3    ; print
        16  [7] LOADK       5 -5    ; 4
        17  [7] CALL        4 2 1
        18  [8] GETGLOBAL   4 -3    ; print
        19  [8] LOADK       5 -6    ; 5
        20  [8] CALL        4 2 1
        21  [1] FORLOOP     0 -17   ; to 5
        22  [10]    RETURN      0 1
    
    0 讨论(0)
  • 2020-12-07 14:10

    We encountered this scenario many times and we simply use a flag to simulate continue. We try to avoid the use of goto statements as well.

    Example: The code intends to print the statements from i=1 to i=10 except i=3. In addition it also prints "loop start", loop end", "if start", and "if end" to simulate other nested statements that exist in your code.

    size = 10
    for i=1, size do
        print("loop start")
        if whatever then
            print("if start")
            if (i == 3) then
                print("i is 3")
                --continue
            end
            print(j)
            print("if end")
        end
        print("loop end")
    end
    

    is achieved by enclosing all remaining statements until the end scope of the loop with a test flag.

    size = 10
    for i=1, size do
        print("loop start")
        local continue = false;  -- initialize flag at the start of the loop
        if whatever then
            print("if start")
            if (i == 3) then
                print("i is 3")
                continue = true
            end
    
            if continue==false then          -- test flag
                print(j)
                print("if end")
            end
        end
    
        if (continue==false) then            -- test flag
            print("loop end")
        end
    end
    

    I'm not saying that this is the best approach but it works perfectly to us.

    0 讨论(0)
  • 2020-12-07 14:11

    I've never used Lua before, but I Googled it and came up with this:

    http://www.luafaq.org/

    Check question 1.26.

    This is a common complaint. The Lua authors felt that continue was only one of a number of possible new control flow mechanisms (the fact that it cannot work with the scope rules of repeat/until was a secondary factor.)

    In Lua 5.2, there is a goto statement which can be easily used to do the same job.

    0 讨论(0)
提交回复
热议问题