Warum beginnen Lua-Arrays (Tabellen) bei 1 statt bei 0?

125

Ich verstehe die Gründe für die Entscheidung dieses Teils von Lua nicht. Warum beginnt die Indizierung bei 1? Ich habe (wie viele andere auch) dieses großartige Papier gelesen . Es scheint mir eine seltsame Ecke einer Sprache zu sein, die sehr angenehm zu lernen und zu programmieren ist. Versteh mich nicht falsch, Lua ist einfach großartig, aber irgendwo muss es eine Erklärung geben. Das meiste, was ich (im Web) gefunden habe, ist nur zu sagen, dass der Index bei 1 beginnt. Punkt.

Es wäre sehr interessant zu lesen, was die Designer zu diesem Thema gesagt haben.

Beachten Sie, dass ich in Lua "sehr" Anfänger bin. Ich hoffe, ich vermisse nichts Offensichtliches an Tischen.

AraK
quelle
23
Der Standardbereich ist ebenfalls global. Die zwei größten Fehlfunktionen von Lua.
Yann Ramin
37
Ich würde ab 1 nicht als Fehlfunktion bezeichnen. Eigentlich macht es mehr Sinn - Programmierer sind einfach so gut ausgebildet, um in 0-basierten Indizierungen aus anderen Sprachen zu denken, dass es uns nicht gefällt. Wir sind auch darauf trainiert, 5/2 = 2 zu denken. Das macht es nicht richtig.
BlueRaja - Danny Pflughoeft
54
@ BlueRaja-DannyPflughoeft: nein. Eine Nullindizierung ist sinnvoller - Menschen sind so gut darin geschult, mit 1 zu zählen, dass Sprachen, die mit 0 beginnen, zunächst verwirrend sind. Aber ich würde Sie gerne hier an Edsger Dijkstra verweisen: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp
11
@nightcracker: Wenn Sie Äpfel auf einem Tisch zählen, zählen Sie den ersten als "eins", den zweiten als "zwei" usw. Niemand zählt den ersten als "null" und fügt am Ende eins hinzu. Von Null aus zu zählen ist einfach unbestreitbar kontraintuitiv. Ja, mir ist klar, dass die Indizierung intern so funktioniert, aber deshalb nennen wir es eine Abstraktion.
BlueRaja - Danny Pflughoeft
9
Ich habe nie die ganze Liebe zur 0-basierten Indizierung verstanden. Es ist gut für Offsets (wie viele Elemente müssen von Anfang an übersprungen werden?) Und Teilsequenzen (0 ≤ x <n), sieht aber für grundlegende Dinge falsch aus (das zweite Element heißt eins? Das zehnte Element entspricht Index neun? WAT?) . Sogar Programmierer zählen ab 1, wenn sie versuchen, eine vom Compiler gemeldete Zeile zu finden ...
marcus

Antworten:

144

Lua stammt von Sol ab, einer Sprache, die für Erdölingenieure ohne formale Ausbildung in Computerprogrammierung entwickelt wurde. Leute, die nicht in Computer geschult sind, finden es verdammt komisch, bei Null zu zählen. Durch die Einführung einer 1-basierten Array- und String-Indizierung konnten die Lua-Designer die Erwartungen ihrer ersten Kunden und Sponsoren nicht verwechseln.

Obwohl ich sie am Anfang auch komisch fand, habe ich gelernt, 0-basierte Arrays zu lieben. Aber ich komme mit Luas 1-basierten Arrays gut zurecht, insbesondere mit Luas generischer forSchleife und dem ipairsOperator - ich kann es normalerweise vermeiden, mir Gedanken darüber zu machen, wie Arrays indiziert werden.

Norman Ramsey
quelle
7
Dies ist nur ein historischer Marketinggrund. Kein vernünftiger Grund, besonders zur Zeit. Und es scheint sogar, dass Sie versuchen, 1-basierte Indizierung zu vermeiden, anstatt sie zu verwenden :)
Eonil
27
@Eonil vermeidet die explizite Indizierung und reduziert Indizierungsfehler.
Dan D.
8
@Eonil historische Gründe sind in der Regel die relevanten. Sie beginnen mit etwas und können es dann nie ändern, da dadurch der gesamte vorhandene Code beschädigt wird. Besonders schlecht für die Indizierung von 0 gegen 1, da die Art und Weise, wie sie unterbrochen wird, ziemlich subtil ist.
CodesInChaos
5
Der Unterschied besteht zwischen 1 von Länge zu Länge und von 0 zu Länge -1, aber in einer for-Schleife < lengthist dies viel praktischer und in den "verrückten 0-basierten Sprachen" leichter zu lesen. Ich gestehe, wenn ich sehe, dass eine Schleife von 1 iteriert,
gehe
45

In der Programmierung in Luas erster Diskussion über Tabellen erwähnen sie:

Da Sie eine Tabelle mit einem beliebigen Wert indizieren können, können Sie die Indizes eines Arrays mit einer beliebigen Zahl beginnen, die Ihnen gefällt. In Lua ist es jedoch üblich, Arrays mit 1 (und nicht mit 0 wie in C) zu starten, und mehrere Einrichtungen halten sich an diese Konvention.

Später, im Kapitel über Datenstrukturen, sagen sie fast dasselbe noch einmal: Die integrierten Funktionen von Lua gehen von einer 1-basierten Indizierung aus.

Auf jeden Fall bietet die Verwendung der 1-basierten Indizierung einige Vorteile. Der #Operator (Länge): t[#t]Zugriff auf den letzten (numerischen) Index der Tabelle und t[#t+1]Zugriff auf 1 nach dem letzten Index. Für jemanden, der noch keiner 0-basierten Indizierung ausgesetzt war, #t+1wäre es intuitiver, über das Ende einer Liste hinauszugehen. Es gibt auch Luas for i = 1,#tKonstrukt, von dem ich glaube, dass es unter dieselbe Kategorie fällt wie der vorherige Punkt, dass "1 auf die Länge" sinnvoller sein kann, als "0 auf die Länge minus 1" zu indizieren.

Wenn Sie jedoch die Denkweise der 0-basierten Indizierung nicht brechen können, kann die 1-basierte Indizierung von Lua sicherlich eher hinderlich sein. Letztendlich wollten die Autoren etwas, das für sie funktionierte ; und ich gebe zu, ich weiß nicht, was ihr ursprüngliches Ziel war, aber es hat sich wahrscheinlich seitdem geändert.

Mark Rushakoff
quelle
16

Mein Verständnis ist, dass dies so ist, nur weil die Autoren dachten, es wäre ein guter Weg, dies zu tun, und nachdem sie die Sprache der Öffentlichkeit zugänglich gemacht hatten, verkalkte sich diese Entscheidung erheblich. (Ich vermute, es wäre die Hölle zu bezahlen, wenn sie es heute ändern würden!) Ich habe darüber hinaus noch nie eine bestimmte Rechtfertigung gesehen.

Dash-Tom-Bang
quelle
6
Mögliche Begründung: C hat es nur getan, weil ein Array im Grunde nur ein Zeiger ist und array[0] == array + 0;und 1-basiertes Zählen natürlicher ist, wenn Array wirklich eine Hash-Tabelle ist.
Richter Maygarden
19
Lua-Indizes sind eigentlich Indizes. Wenn Sie in C Index sagen, meinen Sie wirklich einen Offset.
Alex
8

Vielleicht ein weniger wichtiger Punkt, aber einer, den ich noch nicht erwähnt habe: Es gibt eine bessere Symmetrie in der Tatsache, dass das erste und das letzte Zeichen in einer Zeichenfolge bei 1 bzw. -1 statt bei 0 und -1 liegen.

VXZ
quelle
8
Das ist zwar schön, aber es war nicht der Grund, um am 1.
lhf
3

Lua-Bibliotheken bevorzugen die Verwendung von Indizes, die bei 1 beginnen. Sie können jedoch jeden gewünschten Index verwenden. Sie können 0 verwenden, Sie können 1 verwenden, Sie können -5 verwenden. Es ist sogar in ihrem Handbuch, das unter ( https://www.lua.org/pil/11.1.html) zu finden ist ) zu finden ist.

Tatsächlich ist etwas Cooles hier, dass interne Lua-Bibliotheken EINIGE übergebene Nullen als Einsen behandeln. Seien Sie vorsichtig, wenn Sie ipairs verwenden.
Also das: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"wird wahr sein.

 You can start an array at index 0, 1, or any other value:

-- creates an array with indices from -5 to 5
a = {}
for i=-5, 5 do
  a[i] = 0
end
user2262111
quelle
Gibt es eine Möglichkeit zu machen , ({'a', 'b'})[1]bewerten zu 'b'nicht 'a'aber? Das scheint mir eingebaut zu sein.
Remram
1
({[0] = 'a', 'b'})[1]
user2262111
0

Der wahre Grund ist, dass die Sprache eine Umsetzung der Definition in einem portugiesischen Gesetz ist und das Hauptentwicklungszentrum in Brasilien war. Sie bevorzugen es, die Verwendung von Null oder Leer oder Nichts als Index oder Index zu vermeiden. Die Sprache erlaubt jedoch in einigen Versionen die Verwendung eines anderen Startindex als 1 in einer Tabellenerstellungsfunktion.

Entwickler
quelle
5
Auch wenn dies zutrifft, ist es für die Gestaltung von Lua überhaupt nicht relevant.
lhf
-1

Tabelle [0] gibt IMMER nil (null) zurück, es sei denn, Sie weisen ihm selbst einen Wert zu. table [0] = 'irgendein Wert' und dann gibt Tabelle [0] 'irgendeinen Wert' zurück, den SIE zugewiesen haben.

Hier ein Beispiel:

tbl={'some'}
print('tbl[0]='..tostring(tbl[0]))
print('tbl[1]='..tostring(tbl[1]))
nothing={}
print('nothing[0]='..tostring(nothing[0]))
print('nothing[1]='..tostring(nothing[1]))
nothing[0]='hey'
print('(after assign)\nnothing[0]='..tostring(nothing[0]))
BladeMight
quelle
-11

Es macht für jeden Sinn, dass wenn a

table = {}

Im Moment tableist leer. Also wann

table == {something}

Die Tabelle enthält etwas, also enthält sie Index 1, tablewenn Sie wissen, was ich meine.

Was ich damit gemeint habe, ist, dass diese Tabelle [0] existiert und ihre Tabelle = {}, die leer ist. Jetzt ruft ein Programmierer keine leere Tabelle mehr auf, setzt sie und füllt sie dann aus. Es ist nutzlos, eine leere zu finden Tabelle jedes Mal, wenn Sie es aufrufen möchten, so ist es einfacher, nur eine leere Tabelle zu erstellen.

Mein Englisch wird nicht besser und das ist meine beste Grammatik. Wenn es dir nicht gefällt, kannst du es nicht weiter lesen, aber wenn du -rep für jemanden gibst, der versucht zu helfen, wollen die Leute überhaupt nicht helfen, besonders für etwas wie Grammatik. Ich bin ein Mann mit Zahlen und Vars, nicht mit Grammatik. Es tut uns leid.

Wesker
quelle
4
Ich verstehe nicht, dass eine Tabelle mit 0 bewertet wird. Eine Tabelle kann eine Länge von 0 haben. Dies ist jedoch unabhängig von der Wahl des ersten Index. Ich kümmere mich nicht um kleinere Grammatikfehler, aber ich verstehe den Punkt Ihrer Antwort einfach nicht, weshalb ich abgelehnt habe.
CodesInChaos
Das ist es, was ich erwähne, eine Tabelle kann nicht mit einem 0-Index oder Wert gehalten werden, da wir sie als leere Tabelle verwenden. <, <Wenn Sie etwas haben, wird dieses etwas von 1, "n" dargestellt. Wenn Sie also nichts haben, ist es leer von etwas, das uns zu einem Cero führt, aber der Cero zählt nicht, lua es ist eine Linguage, die praktisch ist, du gehst nicht nach draußen und sagst deinen Freunden, dass du weißt, was ich habe 0 Songs dieser Künstler, egal ob du welche hast oder du nicht. der Punkt seine Tabelle = {} das ist cero eine leere Tabelle
Wesker
5
Ein Array, das den Index 0als einziges Element verwendet, ist noch nicht leer. Tatsächlich unterstützt Lua dies, es ist einfach nicht die Standardkonvention.
CodesInChaos
yup ich stimme dir zu, in einigen anderen Sprachen, aber nicht in lua, lua index 0 existiert nicht, also können wir uns vorstellen, dass es leer ist = 0, oder so stelle ich es mir vor, selbst wenn du den Index auf 0 zwingen kannst, Es funktioniert nicht mit den Tabellenwerten. #table liest keinen 0-Index. Meine Antwort lautet also immer noch, dass es im Grunde genommen wie ein reguläres Ereignis erstellt wurde. Wenn sie dies beabsichtigen oder nicht, ist es nicht wirklich relevant. Sie werden den gesamten Code nicht erneut schreiben wir können nichts dagegen tun: /, ich glaube immer noch, dass es fair ist zu sagen, dass in lua eine leere Tabelle einen 0-Index hat
Wesker