Таблицы в языке lua

При написании кода мы часто будем использовать таблицы, поэтому нам придется разобраться, что вообще собой представляют таблицы в языке lua.
Если вы ранее писали программы хотя бы на одном языке программирования, то наверняка слышали такие понятия как массивы или списки. Так вот в языке lua во всё это заменяют таблицы.

Если же вам ранее еще не приходилось программировать и это ваш первый язык, то читайте данную статью ниже и я постараюсь подробно объяснить что собой представляют в таблицы.

Таблица в языке lua это набор данных, причём тип данных не имеет значение. Таблица может содержать в себе данные одного типа, либо это могут быть смешанные данные, то есть таблица будет содержать в себе разные типы данных.

Для того чтобы лучше понимать что такое таблица, представьте некий контейнер в котором имеются отделы, в которых можно что-то хранить. Вот как раз то что мы будем хранить и будет являться типом. Какие бывают типы можно почитать в главе Переменные в языке lua. Как я уже сказал ранее в таблицах можно хранить смешанные типы данных, то есть в одном отделе у нас могут находиться числа, во втором отделе может находиться текст, а в третьем и вовсе логическое значение. Также нам никто не запрещает хранить в отделах таблицы, то есть получается что в одной таблице будет находиться другая таблица, такие таблицы называются вложенные таблицы.

На картинке ниже я визуально представил как данные располагаются в таблице.

Вложенные таблицы lua

Вложенные таблицы lua

На картинке вы видите 3 таблицы, которые вложены друг в друга. Таблица номер 1 выделена синим цветом. Первый и второй контейнеры данной таблицы содержат числа, целое и десятичное соответственно, третий и четвертый контейнеры содержат текст. Пятый контейнер содержит логическое значение. Шестой контейнер, первой таблицы, содержит в себе другую таблицу, назовем её таблица номер 2. Как видим первые три контейнера таблицы номер 2 содержат дробные числа и целое число, а 4 контейнер содержит в себе третью таблицу. Последняя таблица, выделена зеленым цветом и содержит в себе только даты и время, которые на рисунке представлены в виде текста, но также дата и время может являться таблицей. Теперь я надеюсь вы представляете что такое таблица.

Теперь будем разбираться дальше. У нас имеется таблица и в этой таблице может находиться много контейнеров. В какой-то момент мы решим получить данные из таблицы, и вот тут возникает вопрос, как нам это сделать. Как нам указать из какого именно контейнера мы хотим получить данные? Первое что приходит на ум указать номер контейнера, значит все наши контейнеры должны быть пронумерованы. Действительно, всё так и есть, в таблице можно пронумеровать все контейнеры и таким образом при указании номера контейнера получать необходимые нам данные из таблицы, но это не единственный способ. Контейнеры могут иметь номера 1 2 3 4 5 и так далее, давайте это назовем индексами таблицы. Таким образом у нас получается что таблица содержит индексы и контейнеры, каждому контейнеру присваивается свой индекс, он должен быть уникальным. Так вот индексы как и контейнеры, могут представлять собой любые данные, а не только числа. Можно сделать индексы текстом, например мы можем контейнеры назвать как красный, синий, зелёный, жёлтый и так далее. Обращаться к таким контейнерам следует естественно также текстом. Ну и конечно же индексы могут быть смешанными то есть некоторые индексы могут быть числами, некоторые текстом и так далее.

А теперь будем называть все своими именами. То что мы для лучшего понимания условно называли контейнерами, в таблицах языка lua называется полями, а то что мы условно называли индексами, называется ключами. В итоге это будет звучать так. Таблица содержит поля и ключи. У каждого поля имеется свой уникальный ключ.

С теорией немного разобрались, теперь перейдем к практике.

local nameTable = {};

В этой строке кода мы объявили переменную nameTable, а открытая и закрытая фигурные скобки говорят нам о том что в переменную была помещена таблица. В данном примере таблица не содержит в себе ни одного поля и соответственно ключа, её ещё называют пустой таблицей. Теперь мы можем добавить в эту таблицу данные

nameTable[1] = 148;

В этой строке мы помещаем в поле целое число 148, и присваиваем ключ полю под номером 1. Для того чтобы получить данные из этого поля можно написать следующим образом. Вот полный код:

local nameTable = {};
nameTable[1] = 148;
message("Значение из таблицы = " .. nameTable[1]);

Если мы запустим этот код на выполнение, то у нас появится сообщение со следующим текстом:

Результат вывода информации из таблицы

Результат вывода информации из таблицы

Теперь давайте изменим ключ на текст

local nameTable = {};
nameTable["open"] = 148;
message("Значение из таблицы = " .. nameTable["open"]);

Теперь у нас поле в таблице не находится под номером 1, а имеет текст open. Не забывайте что язык lua является регистро-зависимыv, а значит если вы указали ключ маленькими буквами, то и обращаться тоже нужно маленькими буквами, так как open и Open это два абсолютно разных ключа и ведут к разным полям в таблице.
Если ключ указан текстом, то обращаться к нему можно таким образом

local nameTable = {};
nameTable["open"] = 148;
message("Значение из таблицы = " .. nameTable.open);

После названия таблицы ставим точку и пишем ключ к которому хотим обратиться.

Заполнять таблицу данными можно двумя вариантами, либо сначала объявить таблицу, а потом добавлять в неё данные, либо же сразу при объявлении таблицы добавить в неё необходимые данные.

local nameTable = {};
nameTable["open"] = 148;
nameTable["high"] = 154;
nameTable["low"] = 140;
nameTable["close"] = 150;

local nameTable2 =
{
	["open"] = 148,
	["high"] = 154,
	["low"] = 140,
	["close"] = 150
}

В данном примере я создал 2 таблицы. В первом варианте сначала была создана пустая таблица, а затем в неё были добавлены поля. Во втором же варианте при создании таблицы в неё сразу были добавлены поля. Разницы в этом нет, можно пользоваться любым способом.

И еще один вариант, когда при заполнении таблицы квадратные скобки нужно опускать

local nameTable2 =
{
	open = 148,
	high = 154,
	low = 140,
	close = 150
}

Обратите внимание на запятые между данными, именно через запятую необходимо записывать данные в таблицу.

local nameTable4 =
{
	["subTable"] =
	{
		open = 123,
		high = 150
	},
	subTable2 =
	{
		["low"] = 100,
		["close"] = 130
	}
}

Ещё один пример в котором я создаю таблицы и вкладываю эти таблицы в другую таблицу. В этом примере для наглядности я использовал оба варианта и с квадратными скобками и без них.

Таблицы — это ссылочный тип данных.

Как можно понять из заголовка, таблицы являются ссылочным типом данных, чтобы в этом разобраться необходимо для начала вообще понять что собой представляет ссылочный тип данных.

Возьмем для примера 2 типа данных число и таблица. Числа не являются ссылочным типом данных, а вот таблицы как раз относятся к таким, значит на этих двух примерах и будем разбираться.

Когда мы объявляем числовую переменную, то в памяти компьютера резервируемый для неё место. Если мы объявим еще одну переменную и поместим в неё значение первой переменной, то в памяти у нас будет выделено ещё дополнительное место для второй переменной. Предположим что число занимает одну единицу памяти в компьютере, когда мы объявим вторую переменную и поместим в неё значение первой переменной, то в компьютере будет занято уже две единицы памяти. С таблицами же всё немного иначе, так как это ссылочные типы данных.

local a = 10;
local b = a;

В этом примере мы объявили две переменные. В первую переменную мы поместили число 10, а во вторую переменную мы поместили значение первой переменной, то есть то же число 10. В итоге у нас в компьютере занято две единицы памяти, одна единица памяти для переменной a и вторая единица памяти для переменной b.

С ссылочным типом данных всё обстоит немного иначе. Когда мы объявляем переменную и помещаем в неё таблицу, то на самом деле в эту переменную помещается не сама таблица, а ссылка на эту таблицу. В итоге когда мы копируем значение одной переменной в другую переменную , то на самом деле копируется лишь только ссылка, а не сама таблица.

local aTable = {};
local bTable = aTable;

В этом примере переменная aTable содержит ссылку на таблицу и переменная bTable содержит тоже ссылку на ту же самую таблицу. Посмотрите на картинку ниже.

Таблицы lua ссылочный тип данных

Таблицы lua ссылочный тип данных

Как видите переменная а ссылается на свою ячейку в памяти, а переменная b ссылается на свою ячейку памяти. В то же время как переменная aTable и переменная bTable ссылаются на одну и ту же ячейку в памяти. Это нужно обязательно учитывать.

local aTable = {
	a = 12
}
local bTable = aTable;
bTable.a = 18;
message("Значение из таблицы aTable = " .. aTable.a .. " | " .. "Значение из таблицы bTable = " .. bTable.a);

Посмотрите внимательно на этот пример. Сначала мы объявляем переменную aTable и записываем в неё таблицу, в которой имеется поле а содержащие значение 12. Далее мы копируем таблицу из переменной aTable в переменную bTable. И теперь надеясь что в переменной bTable находится копия, меняем значение в переменной bTable с 12 на 18. В последней строке мы выводим значение из таблицы находящиеся в переменной aTable и значение из таблицы находящийся в переменной bTable. Посмотрите на результат:

Результат копирования таблиц в lua

Результат копирования таблиц в lua

Как видите значение одинаковое. Так как обе переменные ссылаются на одну и ту же таблицу, то есть таблица у нас одна, значение в этой таблице мы изменили. Так что учитывайте этот момент и помните, что таблицы таким образом не копируются, а копируются лишь ссылки.

Надеюсь что вы разобрались что такое ссылочные данные и без труда сможете исправить свою ошибку, если получите неожиданный результат в работе вашего кода.

Постоянная ссылка на это сообщение: https://k-pavel.ru/tablicy-v-jazyke-lua/

avatar

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

  Subscribe  
Подписаться на