Perché gli array Lua (tabelle) iniziano da 1 invece di 0?


125

Non capisco la logica alla base della decisione di questa parte di Lua. Perché l'indicizzazione inizia da 1? Ho letto (come molti altri hanno fatto) questo grande giornale . Mi sembra uno strano angolo di una lingua che è molto piacevole da imparare e programmare. Non fraintendermi, Lua è semplicemente fantastico ma deve esserci una spiegazione da qualche parte. La maggior parte di quello che ho trovato (sul web) sta solo dicendo che l'indice inizia da 1. Full stop.

Sarebbe molto interessante leggere cosa hanno detto i suoi progettisti sull'argomento.

Nota che sono un principiante "molto" in Lua, spero di non perdere qualcosa di ovvio sulle tabelle.


23
Anche l'ambito predefinito è globale. I due maggiori difetti di Lua.
Yann Ramin

37
Non definirei l'inizio da 1 un errore. In realtà ha più senso: i programmatori sono così ben addestrati a pensare in termini di indicizzazione basata su 0 da altri linguaggi che non ci piace. Siamo anche addestrati a pensare 5/2 = 2. Questo non lo rende giusto.
BlueRaja - Danny Pflughoeft

54
@ BlueRaja-DannyPflughoeft: no. L'indicizzazione zero ha più senso: gli umani sono così ben addestrati a iniziare a contare con 1 che le lingue che iniziano con 0 sono inizialmente confuse. Ma mi piacerebbe indirizzarti a Edsger Dijkstra qui: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp

11
@nightcracker: quando conti le mele su un tavolo, conti la prima come "uno", la seconda come "due" ecc. Nessuno conta la prima come "zero" e poi ne aggiunge una alla fine; contare da zero è semplicemente, indiscutibilmente, controintuitivo. Sì, mi rendo conto che è così che funziona internamente l'indicizzazione, ma è per questo che la chiamiamo astrazione.
BlueRaja - Danny Pflughoeft

9
Non ho mai capito tutto l'amore per l'indicizzazione basata su 0. È utile per gli offset (quanti elementi saltare dall'inizio?) E le sottosequenze (0 ≤ x <n), ma sembra sbagliato per le cose di base (il secondo elemento è chiamato uno? Il decimo elemento corrisponde all'indice nove? WAT?) . Anche i programmatori contano da 1 quando cercano di trovare una riga segnalata dal compilatore ...
marcus

Risposte:


143

Lua discende da Sol, un linguaggio progettato per ingegneri petroliferi senza formazione formale in programmazione di computer. Le persone non addestrate in informatica pensano che sia dannatamente strano iniziare a contare da zero. Adottando l'indicizzazione di stringhe e array 1-based, i progettisti di Lua hanno evitato di confondere le aspettative dei loro primi clienti e sponsor.

Anche se all'inizio li ho trovati strani, ho imparato ad amare gli array basati su 0. Ma me la cavo bene con gli array basati su 1 di Lua, specialmente usando il forloop generico di Lua e l' ipairsoperatore: di solito posso evitare di preoccuparmi di come gli array siano indicizzati.


7
Questo è solo un motivo storico di marketing. Nessuna ragione razionale, soprattutto al momento attuale. E sembra che anche tu stia cercando di evitare l'indicizzazione basata su 1 invece di utilizzarla :)
eonil

27
@Eonil effettivamente evitando l'indicizzazione esplicita riduce gli errori di indicizzazione.
Dan D.

8
I motivi storici di @Eonil sono solitamente quelli rilevanti. Inizi con qualcosa e poi non puoi mai cambiarlo, perché romperebbe tutto il codice esistente. Particolarmente negativo per l'indicizzazione 0 contro 1, poiché il modo in cui si interrompe è piuttosto sottile.
CodesInChaos

5
La differenza è tra passare da 1 a Length e da 0 a length -1, ma in un ciclo for < lengthè molto più pratico e facile da leggere sui "linguaggi strani a 0". Confesso che quando vedo un ciclo che si ripete da 1, presumo subito che inizi dal 2 ° elemento: S
Felype

45

Nella prima discussione sulle tabelle di Programming in Lua , menzionano:

Poiché puoi indicizzare una tabella con qualsiasi valore, puoi iniziare gli indici di un array con qualsiasi numero che ti piace. Tuttavia, è consuetudine in Lua avviare array con 1 (e non con 0, come in C) e diverse strutture si attengono a questa convenzione.

Più avanti, nel capitolo sulle strutture dei dati, si dice di nuovo quasi la stessa cosa: che le strutture integrate di Lua assumono un'indicizzazione basata su 1.

Ad ogni modo, ci sono un paio di comodità nell'usare l'indicizzazione basata su 1. Vale a dire, l' #operatore (lunghezza): t[#t]accede all'ultimo indice (numerico) della tabella e t[#t+1]accede a 1 dopo l'ultimo indice. Per qualcuno che non è già stato esposto all'indicizzazione basata su 0, #t+1sarebbe più intuitivo spostarsi oltre la fine di un elenco. C'è anche il for i = 1,#tcostrutto di Lua , che credo rientri nella stessa categoria del punto precedente secondo cui "1 alla lunghezza" può essere più sensato dell'indicizzazione "0 alla lunghezza meno 1".

Ma se non riesci a rompere la mentalità dell'indicizzazione basata su 0, l'indicizzazione basata su 1 di Lua può sicuramente essere più un ostacolo. Alla fine, gli autori volevano qualcosa che funzionasse per loro ; e ammetto che non so quale fosse il loro obiettivo originale , ma probabilmente è cambiato da allora.


16

La mia comprensione è che è così solo perché gli autori pensavano che sarebbe stato un buon modo per farlo, e dopo aver reso pubblico il linguaggio quella decisione si è notevolmente calcata. (Sospetto che ci sarebbe un inferno da pagare se lo cambiassero oggi!) Non ho mai visto una giustificazione particolare oltre a quella.


6
Possibile giustificazione: C lo ha fatto solo perché un array è fondamentalmente solo un puntatore e array[0] == array + 0;, e il conteggio basato su 1 è più naturale quando array è in realtà una tabella hash.
Giudice Maygarden

19
Gli indici Lua sono in realtà indici. In C quando dici indice ciò che intendi veramente è un offset.
Alex

8

Forse un punto meno significativo, ma di cui non ho ancora sentito parlare: c'è una migliore simmetria nel fatto che il primo e l'ultimo carattere di una stringa sono rispettivamente a 1 e -1, invece di 0 e -1.


8
Anche se questo è bello, è stato non è la ragione per iniziare a 1.
LHF

3

Le biblioteche Lua preferiscono usare indici che iniziano da 1. Tuttavia, puoi usare qualsiasi indice tu voglia. Puoi usare 0, puoi usare 1, puoi usare -5. È anche nel loro manuale, che può essere trovato su ( https://www.lua.org/pil/11.1.html ).

In effetti, qualcosa di interessante qui è che le librerie lua interne tratteranno ALCUNI 0 passati come 1. Fai solo attenzione quando usi ipairs.
Quindi: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"sarà vero.

 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

C'è un modo per fare ({'a', 'b'})[1]valutare di 'b'no 'a'però? Mi sembra integrato.
remram

1
({[0] = 'a', 'b'})[1]
user2262111

0

La vera ragione è che la lingua è un'implementazione della definizione in una legge del Portogallo e il principale centro di sviluppo era in Brasile e la loro preferenza è quella di evitare l'uso di zero o vuoto o niente come indice o pedice. Tuttavia, in alcune versioni, la lingua consente l'uso di un indice iniziale diverso da 1 in una funzione di creazione di tabelle.


5
Anche se questo è vero, non è affatto rilevante per come è stato progettato Lua.
lhf

-1

table [0] SEMPRE restituirà nil (null), A MENO CHE tu non gli assegni un valore table [0] = 'some value' e quindi table [0] restituirà 'some value' che TU hai assegnato.

Ecco un esempio:

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]))

-11

Ha senso per tutti che se a

table = {}

Al momento tableè vuoto. Cosi quando

table == {something}

La tabella contiene qualcosa, quindi quello che contiene è l'indice 1 tablese sai cosa intendo.

Quello che volevo dire è che la tabella [0] esiste, e la sua tabella = {}, che è vuota, ora un programmatore non chiamerà una tabella vuota, la imposta e poi la riempie, sarà inutile trovarne una vuota table ogni volta che vuoi chiamarla, quindi è più semplice creare una tabella vuota.

Il mio inglese non migliorerà e questa è la mia migliore grammatica. Se non ti piace, sei libero di non continuare a leggerlo, ma dare -rep per qualcuno che cerca di aiutarti fa sì che le persone non vogliano affatto aiutare, specialmente per qualcosa come la grammatica. Sono un uomo di numeri e variabili, non di grammatica. Scusate.


4
Non capisco il concetto di una tabella con valore 0. Una tabella può avere una lunghezza di 0. Ma questo è indipendente dalla scelta del primo indice. Non mi interessano gli errori grammaticali minori, ma semplicemente non capisco il senso della tua risposta, motivo per cui ho votato in basso.
CodesInChaos

questo è quello che dice, una tabella non può essere tenuta con un indice o un valore 0, poiché la usiamo come una tabella vuota <, <quando hai qualcosa questo qualcosa è rappresentato da 1, "n" quindi quando non hai niente, sei vuoto di qualcosa, che ci porta a un cero, ma il cero non conta, lua è una lingua che viene pratica, non esci e dici ai tuoi amici che sai cosa ho 0 canzoni di quegli artisti, eigther ne hai alcune, o tu Dont. il punto è la sua tabella = {} questo è un tavolo vuoto
Wesker

5
Un array che utilizza l'indice 0come unico elemento non è ancora vuoto. In effetti lua lo supporta, semplicemente non è la convenzione predefinita.
CodesInChaos

sì sono d'accordo con te, su alcune altre lingue, ma non lua, lua index 0 non esiste, quindi possiamo immaginarlo come un vuoto = 0, o è così che lo immagino, anche quando puoi forzare l'indice a essere 0, non funzionerà con i valori della tabella #table non leggerà un indice 0, quindi la mia risposta è ancora che lua è fatto fondamentalmente come un evento normale, ora se lo intendono o no non è davvero rilevante non riscriverai il codice buco, e non possiamo farci niente: /, credo ancora che sia giusto dire che in lua un tavolo vuoto ha un indice 0
Wesker
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.