2015-08-28 7 views
2

Насколько я понимаю, pairs(t) просто возвращает next, t, nil.Lua: Есть ли способ сказать `next`, чтобы начать с определенного ключа?

Если я изменю это на next, t, someKey (где someKey - действительный ключ в моей таблице), то next начните с/после этого ключа?

Я попробовал это на Lua Demo странице:

t = { foo = "foo", bar = "bar", goo = "goo" } 

for k,v in next, t, t.bar do 
    print(k); 
end 

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

+0

«пары» также будут случайным образом перебирать хэш-карту. – hjpotter92

ответ

5

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

Это было представлено в Lua 5.2. См. luai_makeseed.

+0

Зачем производить заказ? – Aubergine18

+1

@ Aubergine18, чтобы избежать атак, которые используют квадратичное или худшее поведение при обработке столкновений в хэш-таблицах. – lhf

+0

Являются ли числовые индексы рандомизированными для защиты от подобных атак? – Aubergine18

2

От luadocumentation:

Порядок, в котором индексы перечислены не указан, даже для числовых индексов. (Для того, чтобы пересекать table в числовом порядке, используйте числовая for.)

+1

Где именно происходит эта случайность? Я не очень хорошо читаю C-код (http://www.lua.org/source/5.3/ltable.c.html), но из того, что я вижу, внутренний индекс таблицы не постоянно рандомизирован. Я мог видеть, как это изменится, если я начну вносить изменения в таблицу (добавление/удаление/обновление элементов), но если я еще не сделал, что внутренний индекс будет статичным? Итак, функция 'next' выполняет рандомизацию? – Aubergine18

+0

... просто для уточнения ... Когда в таблицу добавляется нечисловой ключ, он получает хешированный и этот хеш входит во внутренний индекс. Поэтому после установки некоторых значений порядок может отличаться, но он должен оставаться неподвижным до тех пор, пока в таблицу не будут внесены дальнейшие изменения. Поскольку внутренний индекс таблицы основан на числовых первых, а затем хэшах, и мы знаем, где заканчивается числовая таблица (так что мы знаем, где первый хеш), почему «следующий» всегда начинается с первого хэша? – Aubergine18

+0

@ Aubergine18 Это случайный случай, поскольку таблицы Lua являются hashtables, которые [неупорядочены] (https://en.wikipedia.org/wiki/Hash_table). Значение, которое конкретный хэш ключа не имеет ничего общего с порядком добавления элементов в таблицу. Теперь * внутренне * элементы * делают * имеют порядок, и если вы повторяете одну и ту же таблицу 10 раз подряд, вы будете получать их в одном порядке каждый раз, но это деталь реализации, и вы не можете контролировать ее это заказ. – Mud