Подтвердить что ты не робот

Lua: неявное создание таблицы со строковыми ключами - почему дополнительные скобки?

Скажите, что вы хотите создать таблицу Lua, и все ее ключи являются действительными идентификаторами lua. Затем вы можете использовать синтаксис key=value:

local niceTable = { I=1, like=1, this=1, syntax=1 }

Если ваши строки не являются "идентифицируемыми", тогда вы должны использовать синтаксис ['key']=value:

local operators = { ['*']="Why", ['+']="the", ['/']="brackets", ['?']='?' }

Я немного озадачен этим. Что это за скобки? Что они означают?

4b9b3361

Ответ 1

Они идентифицируют содержащуюся строку как ключ в результирующей таблице. Первая форма, которую вы можете считать равной

local niceTable = {}
niceTable.I = 1;
niceTable.like = 1;

Вторая форма равна

local operators = {}
operators['*'] = "Why";
operators['+'] = "The";

Разница заключается в чисто синтаксическом сахаре, за исключением тех случаев, когда первая использует идентификаторы, поэтому она должна следовать правилам идентификатора, например, не начинается с числа и константы времени интерпретации, а вторая форма использует любую старую строку, поэтому его можно определить во время выполнения, например, и строку, которая не является юридическим идентификатором. Однако результат в принципе тот же. Необходимость скобок легко объясняется.

local var = 5;
local table = {
    var = 5;
};
-- table.var = 5;

Здесь var - это идентификатор, а не переменная.

local table = {
    [var] = 5;
};
-- table[5] = 5;

Здесь var - это переменная, а не идентификатор.

Ответ 2

Обычный синтаксис индексации таблицы - t[val]. Только для строковых ключей Lua предоставляет альтернативный синтаксис, где t.foo в точности эквивалентен t["foo"]. Это чисто синтаксическое удобство, так называемый "синтаксический сахар". Он не добавляет функциональности, он просто дает вам менее суматоху синтаксис для использования строк в качестве названных полей.

Существует много ключей строк, которые не будут работать:

t["hello_world"] => t.hello_world  -- works
t["hello world"] => t.hello world  -- oops, space in the string
t["5 * 3"]       => t.5 * 3        -- oops
t['[10]']        => t.[10]         -- oops

В основном это работает, только если строковый ключ будет действительным идентификатором.

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

t = {
   -- [key]           = value
   [10]               = "ten", -- number key, string value
   ["print function"] = print, -- string key, function value
   ["sub table"]      = {},    -- string key, table value
   [print]            = 111,   -- function key, number value
   ["foo"]            = 123,   -- string key, number value
}

Только если вы используете строковый ключ, который будет работать как действительный идентификатор (без пробелов, содержит только слова, цифры или подчеркивания, и не начинается с числа), вы можете использовать синтаксис ярлыка. Для таблицы выше это будет только "foo":

t = {
   -- [key]           = value
   [10]               = "ten", -- number key, string value
   ["print function"] = print, -- string key, function value
   ["sub table"]      = {},    -- string key, table value
   [print]            = 111,   -- function key, number value
   foo                = 123,   -- string key, number value
}