Ein interessantes Phänomen von Luas Tisch

8

Ich bin neu bei Lua und lerne gerade den Gebrauch von Tisch. Aus Tutorials weiß ich, dass Lua numerische indexierte Elemente und nicht-numerische indizierte Elemente unterschiedlich behandelt, also habe ich selbst einige Tests durchgeführt, und heute habe ich ein interessantes Phänomen gefunden und kann es nicht erklären:

Der Code

%Vor%

bekommt

%Vor%

, weil der Operator # nur numerische indizierte Elemente zählt. Dann habe ich den folgenden Code getestet

%Vor%

Ich bekomme

%Vor%

Bis jetzt denke ich, dass Lua jene diskontinuierlichen Elemente behandelt, die später als nicht numerisch indizierte Objekte hinzugefügt wurden. Aber nachdem ich den Code ein wenig geändert habe

%Vor%

Ich bekomme

%Vor%

Ich bin verwirrt von diesem Phänomen, weiß jemand den Grund? Danke.

(Dieses Phänomen kann in Ссылка ) reproduziert werden

Aktualisierung:

Ich habe diesen Code ausprobiert

%Vor%

Ich bekomme

%Vor%

Dieses Beispiel zeigt, dass Lua eine Tabelle zwischen dünn und dicht konvertiert.

    
SaltyEgg 18.04.2013, 06:53
quelle

2 Antworten

10

Ich habe nicht untersucht, wie der Operator # implementiert ist, aber ich wette, dass durch Hinzufügen der zusätzlichen 100 Indizes der Bereich 1-300 so dicht wird, dass die Indizes 100-300 endet im "array" -Teil der Tabellenimplementierung anstelle des "hash" -Teils.

Aktualisierung:

Ok, ich habe mir die Quelle für die primitive Tabellenlänge angesehen. Wenn der letzte Eintrag im Array-Teil Null ist, durchsucht er das Array nach der niedrigsten "Grenze" (ein Nicht-Null-Index gefolgt von einem Null-Index). Wenn es nicht null ist, entscheidet es, dass die Grenze im Hash sein muss und sucht danach.

Also nehme ich an, dass die Tabelle, die die numerischen Indizes {1, 2, 3, 100..200} enthält, nicht dicht genug ist und der Array-Teil nur {1, 2, 3} enthält. Aber mit der Tabelle, die {1, 2, 3, 100..300} enthält, ist es vermutlich dicht genug, dass der Array-Teil irgendwo innerhalb des 100..300 -Teils endet (ich denke, der Array-Teil ist immer eine Potenz von 2, also kann er nicht enden bei 300 , aber ich bin nicht 100% positiv).

Update 2:

Wenn eine Lua-Tabelle aktualisiert wird, zählt sie die Anzahl der Integer-Schlüssel. Es geht dann alle Potenzen von zwei hinauf, die nicht mehr als die doppelte Anzahl von integralen Schlüsseln sind, und findet die größte Potenz von zwei, die mindestens 50% dicht ist (was bedeutet, dass wenn der Array-Teil so groß war, mindestens 50% aller Werte wäre nicht-Null).

Also mit {1, 2, 3, 100..200} geht es nach oben

%Vor%

Der beste gute Wert ist 2, also endet er mit einer Array-Größe von 2. Da 2 nicht-null ist, durchsucht er den Hash nach der Grenze und findet 3 .

Sobald Sie 201..300 hinzugefügt haben, wird der letzte Schritt

%Vor%

was bewirkt, dass der Array-Teil 1..256 abdeckt, und da 256 nicht-null ist, sucht er erneut nach der Grenze im Hash und erhält 300 '.

Am Ende definiert Lua 5.2 eine "Sequenz" als eine Tabelle mit ausschließlich ganzzahligen Schlüsseln, die bei 1 beginnen und ohne Löcher nach oben gehen. Und es definiert # als nur für Sequenzen gültig. Auf diese Weise kann Lua mit dem seltsamen Verhalten, das Sie bei Tabellen mit Löchern in ihren integrierten Sequenzen bemerkt haben, davonkommen.

    
Kevin Ballard 18.04.2013, 06:59
quelle
5

Die Länge einer Tabelle t ist nur definiert, wenn die Tabelle eine Folge ist, dh die Menge ihrer positiven numerischen Schlüssel ist für eine ganze Zahl n gleich {1..n}.

    
Egor Skriptunoff 18.04.2013 07:11
quelle

Tags und Links