This is the second of the three parts of the article on the basic concepts of the Lua language for the
Corona SDK (if you have not read the
first part I advise you to start with it), in this part we will look at all the data types in the language. You will learn how to initialize variables of all types, use their values, and convert one type to another. This article is extremely important in the matter of learning the language and I tried to add a large number of valuable tips that will allow you to avoid many mistakes when you write your games.
Types of data and their conversion
Lua has 8 data types. Before considering the types I will focus on the standard function of the lua language - type. This function returns a string with the name of the data type of the specified variable or data. An example of using the type function:
n = nil st = '' pi = 3.14 func = function()end t = {} b = true co = coroutine.create(function ()end) print(type(n), type(st), type(pi), type(func), type(t), type(b), type(co))
Next, consider the types of the language Lua.
')
Nil type
This data type defaults to any variable that has no value assigned. All nil variables are nil. You can assign this type to a variable in two ways:
local B = nil
It is worth noting that if a variable has not been initialized in the current scope, its type and value will be nil. A variable having a nil type can be compared in the order of comparing a logical variable having a value of false through the logical not operation, but in reality these types are not similar, I will give an example:
n = nil b = false if not n then
Type boolean
The type boolean is also called a boolean or boolean type, since it is used to implement comparison operations. As already mentioned above, boolean has only 2 possible values of false and true (
false and true ). Since all the comparison operations return exactly these values - the variables of this type can be initialized by assigning the values of the comparative operation to them, it can also be initialized by directly assigning the values. Variables of type boolean can be compared only with equality and inequality operations, as well as directly as a comparison condition in if / elseif
Type number
An extended numerical type, its full description is significantly beyond the scope of this text, so inquisitive users can follow the
link and become familiar with the specification in detail. I can only say that both negative and positive numbers, both integers and floating point, can accommodate this type, at certain levels of positive and negative digit capacity, an automatic transition to the exponential form of numbers takes place, the limits of bit capacity depend on the device’s processor capacity, but currently
Corona SDK has support for Android 4.0.3+, which most likely means that all available devices will be 64 bit. To initialize variables of the number type, it is sufficient either to explicitly assign a value in one of the available formats, either assign the result of a calculation to a variable, or equate it with another variable of this type. I note that any variable of type number in operations of logical comparison returns true, even 0 (and even -1), this should be taken into account by fans of the language c ++ (
and similar ) where 0 is the equivalent of false. I will give an example of operations with the number type:
local a,b = 2,3
Number variables can be performed using a series of numerical operations, the main of which are shown in the example:
a = b + c
Type string
The String type is quite well developed in Lua and, complete with variables, this type comes with many amenities. How to create string variables:
local st1 = 'qwert'
As you noticed from the example, the concatenation (
concatenation ) of strings is performed by two points, and the concatenation process itself can be used as one of the ways to convert a number into a string, I will give an example:
i = 10
As you can see, the translation from number to string is quite simple. I want to note that if you use a string concatenation, it is best to put a space between the clutch operator and operands, but this is not always necessary, but it’s best to get used to it because, firstly, it’s so prettier and clearer, and secondly if one of the operands - a number (
not a variable equal to a number, but a number ), then if you
do not put a space, the error "
malformed number near " will occur. There are more traditional approaches to converting, I will give an example of a transfer to both sides:
i1 = 1 s1 = '11' i2 = tonumber(s1)
I would also like to add that the implicit conversion of a string into a number also exists, but I strongly advise you not to do this — this is completely ugly and will almost certainly lead to a complex error:
When initializing variables of the string type, it is not uncommon for complex moments to arise, which I will briefly describe and present ways to solve them:
- The string has a double or single quotation mark - this is solved in one of two ways: either you need to put the "\" in front of the symbol, this action escapes the character preventing it from completing the open quotation, or use another kind of quotation marks, in Lua as the opening symbol and closing strings can be used in both single and double quotes.
- In the line there is a slash character "\". This causes difficulties. As the interpreter believes that the character standing after the slash is the manager, to solve this problem, you must enter another slash and the string "\\" will be considered as if the character 1
As I wrote above, the string contains a lot of useful amenities, they are implemented using the functions that we consider below.
string.len (s) / s: len ()
The function allows you to determine the length of the string. This, like most of the other functions from the
string library, can be used in two ways, but there are features, below is an example of use:
As you may have noticed, there is an incorrect way to use the function, the comments explain the essence of the error. The rule of using functions common to all other functions of the library, so in the future I will not stop on this in detail.
string.byte (s [, i [, j]]) / s: byte ([i [, j]])
The function returns the character codes of the string from i-th to j-th. Parameters i and j are not required and if you do not specify j, only the code of the i-th element will be returned, if you do not specify i, but specify j, character codes from the first to the jth will be returned, unless you specify i and j will be returned code of the first character in the string. I will give an example of using the function:
local s = 'Example' print(s:byte())
string.char (i1, i2, ...)
One or more parameters with character numbers are passed to the function, and a string equal to all the characters transferred is returned. This function has the opposite purpose with respect to the string.char () function. Examples of using:
print(string.char(65))
string.find (s, pattern [, index [, no_regular]])
s: find (pattern [, index [, no_regular]])
Using the find function, you can find in the string s the position of the pattern pattern or nil if not found. Pattern pattern can be either a string or a regular expression (
you will learn more about regular expressions in a separate chapter ). Consider the simplest version of the use of find. We next turn to the features of the optional parameters:
local s = "Hello Lua!" print(string.find(s,"Lua"))
The index parameter defaults to 1 and this means that the position of the first found entry is returned if you search from the beginning, if you set index to 3, then the third entry in the string will be returned from the beginning, but if -3, then the 3rd entry with end of line. The parameter no_regular is logical, i.e. true / false (true / false), the default parameter is false, if set to true, then the pattern parameter will always be perceived as a regular string, even if you enter a regular expression into it. I will give an example of the expanded use of find:
s = 'La La La La %sLa La' print(s:find('La', 2))
string.format (s, e1, e2, ...)
s: format (e1, e2, ...)
The string.format function creates a formatted string with a set of arguments. At first glance, this function may seem complicated in understanding, but in fact it can greatly simplify many constructions when outputting final information, as well as very conveniently used for other indirect transformations, for example, from number to a string of hexadecimal code. I will give the simplest example:
local sum1,sum2 = 100,200
As you can see, first comes the format of the line, which contains arguments showing how to use the parameters following this parameter. There are 11 (
c, d, E, e, f, g, i, o, u, X, x ) arguments for controlling numeric values and 2 (
s, q ) arguments for managing strings. Then I’ll briefly dwell on each argument and then give examples of usage:
- % s - the parameter is considered a string and is simply inserted
- % q - the parameter is considered a string and is inserted in double quotes
- % c - instead of a number, the symbol will be substituted whose number in the corresponding parameter
- % d - the transferred number will simply be inserted without changing
- % i - the number is represented as an integer with the sign Signed type integer
- % u - the number is represented as an unsigned integer unsigned integer
- % o - the number is converted to the octal number system
- % x,% X - the number is converted to hexadecimal notation, the case of letters in a string will depend on the register of the argument
- % f,% g - the number is considered to be real (floating point), for% f the format is full, for% g shortened to 5 decimal places
- % E,% e - the number will be converted to an exponential form, the register of the letter E in the string will depend on the register of the argument
print(string.format('Number: %d, Signed: %i, Unsigned: %u', 100,-100,-200))
string.lower (s) / s: lower ()
The function converts all characters in a string to lower case:
print(string.lower('Hello World!'))
string.upper (s) / s: upper ()
The function converts all characters in the string to uppercase:
print(string.upper('Hello World!'))
string.rep (s, n) / s: rep (n)
The function is passed a string and the number n, the string is returned repeated n times:
local s = 'Corona ' print(s:rep(3))
string.reverse (s) / s: reverse ()
The function returns the passed string with characters in reverse order:
print(string.reverse('9876543210'))
string.match (s, pattern [, index])
s: match (pattern [, index])
The string.match function finds the occurrence in string s according to the regular expression pattern and returns the capture parameters. About captures using regular expressions will be described in detail in the appropriate section. The function has an optional index parameter, which is equal to 1 by default and determines from which account the entry into the template is to be captured, it should be noted that the negative Index value, by analogy with string.find, is not supported:
local reg = " (%w+):(%d+)"
string.gmatch (s, pattern)
s: gmatch (pattern)
The string.gmacth function is in many respects similar to the string.macth function, but it is intended to be used as an argument in a loop (for more information about loops, see the corresponding section). string.gmacth returns the captures of all occurrences in the string, i.e. no need to specify index, it looks like the following example:
local reg = " (%w+):(%d+)"
Cyclic capture is the most powerful tool for Lua to use which can greatly facilitate many routine operations for parsing complex string values.
string.sub (s, i [, j])
s: sub (i [, j])
The string.sub function returns the substring of the passed string. The substring starts with the i-th character. If the third argument j is not specified, the substring will end at the end of the string. If the third argument is specified, the substring ends with the jth character. If i or j has a negative value, the count comes from the end of the line. I will give examples of use:
local s = 'To be or not to be' print(s:sub(7))
string.gsub (s, pattern, replace [, n])
s: gsub (pattern, replace [, n])
The string.gsub function is one of the most powerful functions of the language. The function has several applications in the simplest case; it replaces in the string s all matches specified in the pattern with the value specified in replace in all places, using n you can limit the number of substitutions, the function will return the resulting string and the number of substitutions:
local s = 'dust ist fantastisch' print(s:gsub('s','S'))
As in the case of string.find, a regular expression (capture) can be used as a search pattern. Capture arguments can be placed according to indices% index_number:
print(string.gsub("lalalalala", "(l)(a)", "%2%1"))
As the replace parameter, a function can be used while parameters captured by a regular expression will be passed to it as parameters.
string.gsub("12 23 34", "(%d+)", print)
A few words about utf-8.
Most of the functions of the string library cannot correctly work with the
utf-8 format for this reason, strings with a national encoding and other special characters will not be correctly processed. To solve these problems, the Corona SDK has a separate
utf library, which has both analogs of functions from the string library and several of its facilities. This library will be discussed in more detail in the context of studying the Corona SDK, or readers can study it themselves.
Type table
The type table (table) is the most basic type of data representation in Lua, in the most general sense, almost all the main entities in a language are tables, even source files. How to create tables and how to work with them:
local t = {}
The exact same table can be initialized in another way:
local t = { key1 = 'name1', key2 = { key3 = 123, }, }
notice these entries are identical:
t['key1'] = 'name1' t.key1 = 'name1'
there is a sense in the first record type only if a numeric value is used as a key:
t[1] = 111
The values recorded in the table are readable and writeable:
print(t.key1)
To clear the entire contents of the table, you can use one of the following methods:
t = {}
If you want to delete one of the table keys, this can be done in two ways:
t.key1 = nil
The most natural way to initialize tables in Lua is to create a numbered array, this is done in the following way:
local t = {23, 45, 3.14, 'vasia', {12, 'a'}}
In fact, if you do not specify the key when initializing the table, the numbering occurs in the order of increasing starting 1 (for most developers, numbering from 0 is more natural, but in Lua it is not so, you need to remember about it), so The initialized table actually looks like this:
local t = { [1] = 23, [2] = 45, [3] = 3.14, [4] = 'vasia', [5] = { [1] = 12, [2] = 'a', }, }
As you can see, “under the hood” quite significant transformations took place with the data. Numbered tables in Lua have special properties, for example, by adding the # symbol to the table name, you get the number of strictly numbered values in the table:
print(#t)
If you add to the table a new strictly numbered key obtained through # the size of the table will increase:
t[#t+1] = 'kolia' print(#t)
If you delete one of the keys by assigning nil, for example, the key [3] the continuous part of the numbered array decreases to just 2 keys [1] and [2], which cannot lead to further errors due to misunderstanding, for this reason I advised above to delete Keys from the table using table.remove, as with this, if you delete the key, the other strictly numbered values will be shifted:
After correct removal of the key, the table will look like:
local t = { [1] = 23, [2] = 45, [3] = 'vasia', [4] = { [1] = 12, [2] = 'a', }, [5] = 'kolia', }
You can add other unnumbered keys to the strict-numbered table, this will not affect the performance of the table, but these keys will also not be taken into account when getting the size through #:
t.key = 'name1' print(t.key, #t)
To bypass all the numbered values of the table by the cyclic operation, there is a function ipairs, it is used as an argument of the for loop by analogy with string.gmatch:
for key, value in ipairs(t) do print(key, value) end
If you want to bypass the cycle all values including those not strictly numbered, use the pairs function:
for key, value in pairs(t) do print(key, value) end
Note? that when using pairs, the sequence of outputting values is not strict, but in general rather confusing, this should be taken into account. In conclusion, I want to note that you can use pairs / ipairs as you pass the value of the table, or by creating it directly into a call like this:
for key, value in ipairs{10,20,30} do print(key, value) end
Function type
The function type has all user-defined functions and standard language functions. I will give an example:
local summ = function(a,b) return a + b end print(type(summ))
You will learn more about how to use functions in the appropriate section.
Thread type
Thread is a separate thread of code execution. I will try to briefly explain what it is. All code of your Lua project is executed in a single execution thread, if there is a need to execute an object of type thread is created in a separate thread. The following code is used for creation:
thread, , coroutine.resume thread. - . coroutine.yield(), . coroutine.resume. , . Those. coroutine.resume .
, . , , .
userdata
userdata Lua , C(). Those. Lua userdata. , .
Conclusion
Lua ,
Corona SDK ,
.