Типы данных в Lua

Lua — это язык с динамической типизацией. Переменным не нужны определения типов; вы просто присваиваете значения переменным. Значения можно хранить в переменных, передавать как параметры или возвращать как результаты.

В Lua есть 8 базовых типов: nil, boolean, number, string, userdata, function, thread и table.

Тип данныхОписание
nilЭто самый простой тип. К этому типу относится только значение nil, представляющее недопустимое значение (эквивалентно false в условных выражениях).
логическое значениеСодержит два значения: false и true.
числоПредставляет вещественное число с плавающей запятой двойной точности.
stringСтроки представляются парой двойных или одинарных кавычек.
функцияФункции, написанные на C или Lua.
userdataПредставляет произвольные структуры данных C, хранимые в переменных.
threadПредставляет независимый поток выполнения, используемый для выполнения сопрограмм.
tableТаблица в Lua на самом деле является "ассоциативным массивом". Индекс массива может быть числом, строкой или таблицей. В Lua таблицы создаются через "конструкторные выражения". Простейшее конструкторное выражение — {}, используемое для создания пустой таблицы.

Мы можем использовать функцию type для проверки типа заданной переменной или значения:

Пример

print(type("Hello world"))      --> string
print(type(10.4*3))             --> number
print(type(print))              --> function
print(type(type))               --> function
print(type(true))               --> boolean
print(type(nil))                --> nil
print(type(type(X)))            --> string

nil (пусто)

Тип nil указывает на отсутствие допустимого значения. У него есть только одно значение — nil. Например, вывод переменной, которой не было присвоено значение, выведет nil:

> print(type(a))
nil
>

Для глобальных переменных и таблиц nil также обладает эффектом «удаления». Присвоение значения nil глобальной переменной или переменной в таблице равносильно их удалению. Запустите следующий код, чтобы узнать:

tab1 = { key1 = "val1", key2 = "val2", "val3" }
for k, v in pairs(tab1) do
    print(k .. " - " .. v)
end
 
tab1.key1 = nil
for k, v in pairs(tab1) do
    print(k .. " - " .. v)
end

При сравнении nil следует добавлять двойные кавычки.":

> type(X)
nil
> type(X)==nil
false
> type(X)=="nil"
истина
>

type(X)==nilРезультат —falseПричина в том, что type(X) фактически возвращает"nil"строку, то есть строковый тип:

type(type(X))==string

boolean (логический тип)

Логический тип имеет только два возможных значения: true и false. Lua воспринимает false и nil как ложные, все остальные значения как истинные, и число 0 тоже истинно:

Пример

print(type(true))
print(type(false))
print(type(nil))
 
if false or nil then
    print("Хотя бы одно истинно")
else
    print("И false, и nil ложны")
end

if 0 then
    print("Число 0 истинно")
else
    print("Число 0 ложно")
end

Результат выполнения приведённого выше кода следующий:

$ lua test.lua 
boolean
boolean
nil
false 和 nil 都为 false
数字 0 是 true

number (Number)

В Lua по умолчанию только один тип number -- double (double precision) (тип по умолчанию можно изменить в определениях luaconf.h). Следующие обозначения все считаются типами number:

Пример

print(type(2))
print(type(2.2))
print(type(0.2))
print(type(2e+1))
print(type(0.2e-1))
print(type(7.8263692594256e-06))

Результат выполнения приведённого выше кода:

number
number
number
number
number
number

строка (String)

Строки представляются парой двойных или одинарных кавычек.

string1 = "this is string1"
string2 = 'this is string2'

Вы также можете использовать двойные квадратные скобки "[[]]" для представления "блока" строки.

Пример

html = [[
<html>
<head></head>
<body>
<a href="http://www.example.com/">Пример учебного руководства</a>
</body>
</html>
]]

print(html)

Результат выполнения следующего кода:

<html>
<head></head>
<body>
    <a href="../index.html">Example</a>
</body>
</html>

При выполнении арифметических операций с числовой строкой Lua попытается преобразовать эту числовую строку в число:

> print("2" + 6)
8.0
> print("2" + "6")
8.0
> print("2 + 6")
2 + 6
> print("-2e2" * "6")
-1200.0
> print("error" + 1)
stdin:1: попытка выполнить арифметическую операцию над строковым значением
трассировка стека:
        stdin:1: в главном блоке
        [C]: in ?
>

В приведённом выше коде "error" + 1 вызывает ошибку. Для конкатенации строк используется .., например:

> print("a" .. 'b')
ab
> print(157 .. 428)
157428
> 

Используйте # для вычисления длины строки, указывая его перед строкой, как в следующем примере:

Пример

> len = "www.example.com"
> print(#len)
14
> print(#"www.example.com")
14
>

table (Таблица)

В Lua таблицы создаются с помощью "выражений-конструкторов". Простейшее выражение-конструктор — {}, оно используется для создания пустой таблицы. Вы также можете добавить некоторые данные в таблицу и инициализировать таблицу напрямую:

Пример

-- Создать пустую таблицу
local tbl1 = {}
 
-- Прямая инициализация таблицы
local tbl2 = {"apple", "pear", "orange", "grape"}

Таблица в Lua на самом деле является "ассоциативным массивом". Индекс массива может быть числом или строкой.

Пример

-- файл скрипта table_test.lua
a = {}
a["key"] = "value"
key = 10
a[key] = 22
a[key] = a[key] + 11
for k, v in pairs(a) do
    print(k .. " : " .. v)
end

Результат выполнения скрипта:

$ lua table_test.lua 
key : value
10 : 33

В отличие от массивов в других языках, использующих 0 в качестве начального индекса, в Lua начальный индекс таблицы по умолчанию обычно начинается с 1.

Пример

-- файл скрипта table_test2.lua
local tbl = {"apple", "pear", "orange", "grape"}
for key, val in pairs(tbl) do
    print("Key", key)
end

Результат выполнения скрипта:

$ lua table_test2.lua 
Key    1
Key    2
Key    3
Key    4

Таблица не имеет фиксированной длины. При добавлении новых данных длина таблицы автоматически увеличивается. Таблицы, которые не инициализированы, равны nil.

Пример

-- файл скрипта table_test3.lua
a3 = {}
for i = 1, 10 do
    a3[i] = i
end
a3["key"] = "val"
print(a3["key"])
print(a3["none"])

Результат выполнения скрипта:

$ lua table_test3.lua 
val
nil

function (Функция)

В Lua функции считаются «объектами первого класса». Функции можно хранить в переменных:

Пример

-- файл скрипта function_test.lua
function factorial1(n)
    if n == 0 then
        return 1
    else
        return n * factorial1(n - 1)
    end
end
print(factorial1(5))
factorial2 = factorial1
print(factorial2(5))

Результат выполнения скрипта:

$ lua function_test.lua 
120
120

Функции можно передавать в качестве аргументов в виде анонимных функций:

Пример

-- файл скрипта function_test2.lua
function testFun(tab,fun)
        for k ,v in pairs(tab) do
                print(fun(k,v));
        end
end


tab={key1="val1",key2="val2"};
testFun(tab,
function(key,val)-- Анонимная функция
        return key.."="..val;
end
);

Результат выполнения скрипта:

$ lua function_test2.lua 
key1=val1
key2=val2

thread (Поток)

В Lua главный поток — это корутина. Он похож на поток. У него есть собственный независимый стек, локальные переменные и указатель инструкций, и он может совместно использовать глобальные переменные и большинство других вещей с другими корутинами.

Разница между потоками и корутинами: несколько потоков могут выполняться одновременно, но в любой момент времени может выполняться только одна корутина, и выполняющаяся корутина приостанавливается только тогда, когда её приостанавливают.


userdata (Пользовательский тип)

userdata — это определяемый пользователем тип данных, используемый для представления типа, созданного приложением или библиотекой языка C/C++. Он может сохранять данные любого типа данных C/C++ (обычно структуры и указатели) в переменные Lua для вызова.

Другие расширения