Гибридный массив Lua и хэш-таблица; он существует где-нибудь еще?
реализация Lua таблиц сохраняет свои элементы в двух частях: часть массива и хэш-часть.
существует ли такая вещь в каких-либо других языках?
взгляните на раздел 4, таблицы, в реализация Lua 5.0.
4 ответов
эта идея была оригинальной с Роберто Ierusalimschy и остальной частью команды Lua. Я слышал, как Роберто говорил об этом на семинаре MIT Lightweight Languages в 2003 году, и в этом разговоре он обсуждал предыдущую работу и убедительно доказывал, что идея была новой. Не знаю, скопировали ли его с тех пор другие языки.
исходный Awk имеет несколько более ограниченную языковую модель, чем Lua; либо число, либо строка могут использоваться в качестве ключа в массиве, но сами массивы не являются первоклассными значениями: массив должен иметь имя, а массив нельзя использовать в качестве ключа в массиве.
Что касается реализации, я проверил источники для исходного Awk, поддерживаемого Брайаном Керниганом, и реализация Awk использует хэш-таблицу, а не гибридную структуру массива/таблицы Lua. Различие важно, потому что в Lua, когда таблица используется с последовательными целочисленными ключами, накладные расходы пространства такие же, как для массива C. Это не true для оригинального Awk.
Я не потрудился исследовать все более поздние реализации awk, например, Gnu Awk, mawk и так далее.
EDIT:это не отвечает на вопрос, который был о реализации.
на awk также сделал это.
интересно, как некоторые языки объединяют операции, которые отличаются в других:
- список индексации -
a[10]
- ассоциативной индексации -
a['foo']
- доступ к полю объекта -
a.foo
- вызовы функций / методов -
a('foo')
/a.foo()
очень неполные примеры:
Perl-редкий язык, где последовательное / ассоциативное индексирование имеет отдельный синтаксис -
a[10]
/a{'foo'}
. AFAIK, объектные поля сопоставляются с одной из других операций, в зависимости от того, какой реализатор класса хотел использовать.в Python все 4 различны; последовательное / ассоциативное индексирование использует тот же синтаксис, но отдельные типы данных оптимизированы для их.
в Ruby поля объектов-это методы без аргументов -
a.foo
.в JavaScript поля объектов
a.foo
синтаксис сахара для ассоциативной индексацииa['foo']
.в Lua и AWK ассоциативные массивы также используются для последовательного индексирования -
a[10]
.на Arc, последовательное и ассоциативное индексирование выглядит как вызовы функций -
(a 10)
/(a "foo")
, и я думаюa.foo
синтаксис сахар для этого тоже (?).
самое близкое, что я могу придумать-это JavaScript - вы создаете массив с new Array()
, а затем перейдите к индексу по номеру или по строковому значению. Вполне возможно, что по соображениям производительности некоторые реализации Javascript предпочитают делать это с использованием двух массивов по причинам, указанным в документации Lua, с которой вы связаны.
ArrayWithHash - это быстрая реализация гибрида array-hashtable в C++.
поскольку C++ является статически типизированным языком, в ArrayWithHash разрешены только целочисленные ключи (невозможно вставить строку или ключ указателя). Другими словами, это что-то вроде массива с резервной копией хэш-таблицы для больших индексов. Также он использует другую реализацию хэш-таблицы, которая менее эффективна для памяти, чем реализация таблицы Lua.