From the author
This article contains only the most basic information about Lua. What prompted me to create it was the lack of such a short guide on this language on the Internet. I only found a shortened version in the documentation, but it also seemed quite large to me. So, if that’s what you’re looking for, let’s start
Introduction
Lua is a powerful, lightweight scripting language that is used in a wide range of applications, from web servers to video games. It is known for its simplicity and flexibility, making it a popular choice for programmers of all skill levels.
The peculiarity of Lua is that while it supports object-oriented programming (OOP) principles, it does not have built-in classes like some other languages. Instead, Lua uses tables to simulate classes. Tables are essentially associative arrays that can contain keys and values, which can be any data type, including functions. Furthermore, arrays in Lua start with an index of 1, not 0 as in many other programming languages.
Variables
In Lua, you can declare a variable using the local
keyword, followed by the variable name. If you want the variable to be global, you can omit the local
keyword.
local x = 10
y = 20
Data Types
Lua has eight basic types: nil
, boolean
, number
, string
, userdata
, function
, thread
, and table
.
Operators
Lua supports a variety of operators, including arithmetic, relational, logical, and bitwise operators.
Arithmetic operators include: +
(addition), -
(subtraction), *
(multiplication), /
(division), ^
(exponentiation), and %
(modulus).
Relational operators include: ==
(equal to), ~=
(not equal to), <
(less than), >
(greater than), <=
(less than or equal to), and >=
(greater than or equal to).
Logical operators include: and
(logical AND), or
(logical OR), and not
(logical NOT).
Bitwise operators, available from Lua 5.2 onwards, include: &
(AND), |
(OR), ~
(XOR), <<
(left shift), >>
(right shift), and ~
(NOT).
It's important to note that Lua uses "short-circuit" evaluation for its logical operators, meaning it will stop evaluating as soon as the outcome is determined.
local a = true
local b = false
if a or b then
print("At least one of the conditions is true.")
end
In this case, Lua will stop evaluating as soon as it encounters the a
variable, because it's true
, and that's enough to determine the outcome of the or
operation. It won't even check the value of b
.
Tables
Tables in Lua are the only data structure, and they can be used to represent arrays, sets, records, graphs, trees, etc.
local numbers = {1, 2, 3}
local titles = {['luna'] = 'devops engineer', ['rudy'] = 'backend developer'}
local wtf = {1, 2, ['pithon'] = 'ml engineer'}
a = {} -- create a table and store its reference in `a'
k = "x"
a[k] = 10 -- new entry, with key="x" and value=10
a[20] = "great" -- new entry, with key=20 and value="great"
print(a["x"]) --> 10
k = 20
print(a[k]) --> "great"
a["x"] = a["x"] + 1 -- increments entry "x"
print(a["x"]) --> 11
Control Structures
Lua supports the usual control structures: if
statements, while
loops, and for
loops.
if x > y then
print("x is greater than y")
else
print("x is not greater than y")
end
Example of a for
loop:
for i = 1, 10 do
print(i)
end
Iterating Over Tables
Iterating over tables in Lua is achieved through the use of loop constructs. A common method is using the pairs
function with a for
loop. This function returns a key-value pair for each item in the table, allowing you to access both the index and value in each iteration.
local tbl = {apple = "fruit", carrot = "vegetable", lion = "animal"}
for key, value in pairs(tbl) do
print(key, value)
end
In this example, the for
loop will iterate over each key-value pair in the table. The pairs
function is particularly useful when working with tables where the keys are not just numerical values or when the keys are not in sequence.
It's important to note that the pairs
function does not guarantee any particular order when iterating over the table.
Another function, ipairs
, is used specifically for tables with integer keys that are in sequence. It stops iterating once it encounters a nil
value.
Arrays are just a special kind of table, and you can iterate over them using a for
loop.
You can get length of an array by #
as simple as of a string.
local array = {1, 2, 3, 4, 5}
for i = 1, #array do
print(array[i])
end
In this example, #array
gives the length of the array, and array[i]
accesses the i
-th element in the array.
There’s no arr[0] in lua. Every array starts with 1 index
Functions
You can declare a function in Lua using the function
keyword, followed by the function name and parameters.
function add(x, y)
return x + y
end
Object-Oriented Programming in Lua
Lua supports object-oriented programming (OOP) principles, but it does not have built-in classes like some other languages. Instead, Lua uses tables to simulate classes. Tables are essentially associative arrays that can contain keys and values, which can be any data type, including functions.
Here is a simple example of how to implement a class in Lua:
Person = {}
Person.__index = Person
function Person.new(name, age)
local self = setmetatable({}, Person)
self.name = name
self.age = age
return self
end
function Person:greet()
print("Hello, my name is " .. self.name .. " and I am " .. self.age .. " years old.")
end
-- To create a new instance of the class and call a method:
local john = Person.new("John", 25)
john:greet()
In this example, Person
is a table that serves as a class. The __index
metamethod is set to the Person
table itself, which allows instances of the class to access its methods.
The new
function is a constructor that creates a new instance of the Person
class. It uses setmetatable
to associate the Person
methods with the new instance.
The greet
function is a method that all Person
instances will have access to.
Lua also supports inheritance, which allows one class to inherit the properties and methods of another class. This can be done by setting the __index
metamethod of the child class to the parent class. Here is an example:
-- Assuming the Person class has been defined...
Student = setmetatable({}, Person)
Student.__index = Student
function Student.new(name, age, grade)
local self = Person.new(name, age) -- Create a Person instance
setmetatable(self, Student) -- Change its metatable to Student
self.grade = grade
return self
end
function Student:study()
print(self.name .. " is studying.")
end
-- To create a new instance of the Student class:
local jane = Student.new("Jane", 20, "A")
jane:study() -- Outputs: "Jane is studying."
In this example, Student
is a subclass of Person
. The new
function in Student
calls the new
function in Person
to create a Person
instance, then changes its metatable to Student
, effectively turning it into a Student
instance.
Threads
In Lua, a thread represents an independent execution line. Lua supports multithreading by using coroutines, which are a generalization of subroutines. Coroutines in Lua are a type of collaborative multitasking where the switch from one task to another is done explicitly by a coroutine. Lua's threads are not operating system threads, but they can be used to simulate multithreading.
Threads are a type of value in Lua and they are manipulated just like any other value. You can create a thread with the coroutine.create()
function, which returns a value of type thread. This function takes a single argument: a Lua function that the thread will execute.
co = coroutine.create(function ()
print("Hello, World!")
end)
coroutine.resume(co) -- Outputs: "Hello, World!"
In this example, coroutine.create()
creates a new coroutine with the specified function and coroutine.resume()
starts or continues the execution of a coroutine.
A thread in Lua can be in one of three states: suspended, running, or dead. When you create a thread, it starts in the suspended state. Then, when you call coroutine.resume()
, it goes to the running state. If the function finishes its execution or if an error occurs, the thread goes to the dead state. You can check the status of a thread with the coroutine.status()
function.
Coroutines provide a lot of flexibility, as they can yield (pause) at any point in their execution and can be resumed later from where they left off. This is done using the coroutine.yield()
and coroutine.resume()
functions.
Note that coroutines are not a parallelism mechanism. Even though they can be used to simulate concurrency, only one coroutine runs at a time.
Conclusion
This is a very basic introduction to Lua. Lua is a powerful language that has a lot to offer, so don't hesitate to dive deeper and explore what you can do with it!
Top comments (0)