Grandelf
Esteemed Member
Hello there,
I am making this topic because since Lua 5.2 we have acces to this amazing thing called a 'goto' statement,
which is absolutely awesome in my opinion. I haven’t seen anyone using it yet, which can either be that most of the people here
doesn’t exactly know how it works or haven’t heard of it yet, or it can simply be that no one has found any use for it.
Either way I felt like making a small tutorial for it.
What is a goto statement exactly?
A goto statement is much like a 'return' or 'break' statement, it basically stops some code from running.
However a goto statement skips code rather than completely stopping all the code in a loop (break) or function (return).
To skip code and 'goto' a certain point in your code however, you need something so the goto statement knows where to go to.
This is called a label.
Knowing all this, it is clear that goto needs some kind of variable passed into it, and a label has to be made somehow,
somewhere in the code. As an example I decided to use the 'continue' statement from languages like C++ or Java.
Before the goto statement was introduced there was no way to replicate this behavior in Lua.
For those of you who don’t know what a continue statement does, it basically skips to the next iteration inside a loop.
The array will now contain the following: {2, 4, 3, 8, 10, 12, 14, 16, 18, 20}. As you can see it multiplied every number by 2,
except for the third element, because a continue statement was called and it skipped the rest of the code.
The continue statement in Lua.
Now lets implement this behavior in Lua, using a goto statement. Like I said before,
a goto statement requires a label which will be the argument for goto. Now how do you make this label?
That may be more easy than you would’ve expected. To make a label you simply use 2 colons, followed by the label name followed by two more colons.
After making the label you will have to place it inside your code, keep in mind that wherever you put this label,
that is where the goto statement will jump to as seen later in the continue example which we will be making.
Now we know what a goto statement is, and how we make a label it is time use the goto statement. To start making our continue statement,
we’re going to need a label name. Because we’re making a continue statement, I am going to call this label continue.
The code we’re going to use will be the same as the previous example, but in Lua.
Now to implement a continue statement, we will have to add the continue label in the code on a place where we want the code to jump to.
Seeing as we want to skip that iteration and go to the next one, we can simply place the label after ‘arr = arr *2;’.
Then it will skip to the end of the iteration and continue the next iteration. After that, all that is left to do is call the ‘goto labelname’ and we’re done.
The goto statement outside a loop.
Do note that unlike a continue statement, a goto statement does not have to be called inside a loop. Another simple example to illustrate a goto statement outside a loop would be:
In this code, we simply start off by deciding what code to run, it has a 50% chance to run codeA, otherwise it will run codeB.
Therefor there are two possible outcomes, that it will print to the console. This will either be, ’10, 0’ or ’0, 10’ depending on whether it ran codeB or codeC.
Note: The return statement will actually do the job of stopping the code from running both codeA aswell as codeB.
For those of you, who would like to see more examples of how this works, you can check out this link: http://lua-users.org/wiki/GotoStatement.
I hope this was useful to some people, in my opinion this is a really powerful tool that can be useful in a lot of situations.
Grandelf.
Edit: There seems to be some kind of debate going on whether to use this or not, so I am simply going to say this:
Everyone should decide for themselves if they want to use this or not, knowing about goto on the other hand
isn't going to harm you, and that's exactly the point of this tutorial.
In this tutorial I gave two examples, the first one using continue, is something I would use and is actually really helpful in my opinion.
The second example in this tutorial is purely there to illustrate a goto statement outside of a loop.
To illustrate the use of goto a bit more I have written a small script that will generate a code under two conditions.
In this script I used two labels 'continue' and 'redo', note that I could've used only continue however this way
you're basically making sure something is how you want it to be, before processing it. Also will it illustrate that you can
jump backwards aswell instead of just forward like in the previous examples.
I am making this topic because since Lua 5.2 we have acces to this amazing thing called a 'goto' statement,
which is absolutely awesome in my opinion. I haven’t seen anyone using it yet, which can either be that most of the people here
doesn’t exactly know how it works or haven’t heard of it yet, or it can simply be that no one has found any use for it.
Either way I felt like making a small tutorial for it.
What is a goto statement exactly?
A goto statement is much like a 'return' or 'break' statement, it basically stops some code from running.
However a goto statement skips code rather than completely stopping all the code in a loop (break) or function (return).
To skip code and 'goto' a certain point in your code however, you need something so the goto statement knows where to go to.
This is called a label.
How do I use a goto statement?A goto statement jumps the execution of a program to a corresponding label.
Knowing all this, it is clear that goto needs some kind of variable passed into it, and a label has to be made somehow,
somewhere in the code. As an example I decided to use the 'continue' statement from languages like C++ or Java.
Before the goto statement was introduced there was no way to replicate this behavior in Lua.
For those of you who don’t know what a continue statement does, it basically skips to the next iteration inside a loop.
To illustrate this I have written a small code, that will show you the use of continue.The continue statement passes control to the next iteration of the nearest enclosing do, for, or while statement in which it appears, bypassing any remaining statements in the do, for, or while statement body.
Code:
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < arr.length; i++) do {
/* If the index = 3 then we skip this iteration and go to the next iteration
which has an index of 4. */
if (i == 3)
continue;
arr[i] = arr[i]*2;
}
except for the third element, because a continue statement was called and it skipped the rest of the code.
The continue statement in Lua.
Now lets implement this behavior in Lua, using a goto statement. Like I said before,
a goto statement requires a label which will be the argument for goto. Now how do you make this label?
That may be more easy than you would’ve expected. To make a label you simply use 2 colons, followed by the label name followed by two more colons.
After making the label you will have to place it inside your code, keep in mind that wherever you put this label,
that is where the goto statement will jump to as seen later in the continue example which we will be making.
Now we know what a goto statement is, and how we make a label it is time use the goto statement. To start making our continue statement,
we’re going to need a label name. Because we’re making a continue statement, I am going to call this label continue.
Code:
::continue::
Code:
local arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for i=1, #arr do
if (i == 3) then
-- The continue statement, which we do not have yet.
end
arr[i] = arr[i] *2;
end
Seeing as we want to skip that iteration and go to the next one, we can simply place the label after ‘arr = arr *2;’.
Then it will skip to the end of the iteration and continue the next iteration. After that, all that is left to do is call the ‘goto labelname’ and we’re done.
Code:
local arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for i=1, #arr do
if (i == 3) then
goto continue;
end
arr[i] = arr[i] *2;
::continue::
end
The goto statement outside a loop.
Do note that unlike a continue statement, a goto statement does not have to be called inside a loop. Another simple example to illustrate a goto statement outside a loop would be:
Code:
local a = 0;
local b = 0;
-- 50% chance of going to codeA otherwise codeB.
if math.random(2) == 1 then
goto codeA;
else
goto codeB;
end
::codeA:: do
a = a + 10; return print(a, b);
end
::codeB:: do
b = b + 10; return print(a, b);
end
Therefor there are two possible outcomes, that it will print to the console. This will either be, ’10, 0’ or ’0, 10’ depending on whether it ran codeB or codeC.
Note: The return statement will actually do the job of stopping the code from running both codeA aswell as codeB.
For those of you, who would like to see more examples of how this works, you can check out this link: http://lua-users.org/wiki/GotoStatement.
I hope this was useful to some people, in my opinion this is a really powerful tool that can be useful in a lot of situations.
Grandelf.
Edit: There seems to be some kind of debate going on whether to use this or not, so I am simply going to say this:
Everyone should decide for themselves if they want to use this or not, knowing about goto on the other hand
isn't going to harm you, and that's exactly the point of this tutorial.
In this tutorial I gave two examples, the first one using continue, is something I would use and is actually really helpful in my opinion.
The second example in this tutorial is purely there to illustrate a goto statement outside of a loop.
To illustrate the use of goto a bit more I have written a small script that will generate a code under two conditions.
In this script I used two labels 'continue' and 'redo', note that I could've used only continue however this way
you're basically making sure something is how you want it to be, before processing it. Also will it illustrate that you can
jump backwards aswell instead of just forward like in the previous examples.
Code:
-- A simple script that will generate a code under two conditions,
-- you can't have 2 of the same digits in a row and we are only
-- using even numbers.
local codeLength = 10;
local function generateCode()
local str = "";
while #str ~= codeLength do
::redo::
local number = math.random(9);
-- The number must be different from the last one before
-- it will be taken into consideration.
if number == tonumber(str:sub(#str, #str)) then
goto redo; -- Obviously we could've used continue here aswell.
elseif number %2 ~= 0 then -- Number is different so we consider using it.
goto continue; -- Number declined.
end
str = str .. number;
::continue::
end
return str;
end
print(generateCode());
Last edited: