Tabelle

Il tipo di tabella implementa array associativi. Un array associativo è un array che può essere indicizzato non solo con i numeri, ma anche con le stringhe o qualsiasi altro valore della lingua, ad eccezione di zero. Inoltre, le tabelle non hanno dimensione fissa; è possibile aggiungere come molti elementi come si desidera una tabella in modo dinamico. Tabelle sono la principale (in realtà, l'unico) meccanismo di strutturazione dei dati in Lua, e potente. Usiamo tabelle per rappresentare array ordinari, tabelle dei simboli, set, dischi, code e altre strutture di dati, in modo semplice, uniforme e modo efficiente. Lua utilizza le tabelle per rappresentare pacchetti. Quando scriviamo io.read, si intende "la lettura voce dalla io pacchetto". Per Lua, che significa "indice il tavolo io utilizzando la stringa" leggere "come la chiave".

Tavoli in Lua sono né valori né variabili; sono oggetti. Se si ha familiarità con gli array in Java o schema, allora avete una buona idea di ciò che intendiamo. Tuttavia, se la vostra idea di una matrice viene da C o Pascal, è necessario aprire la mente un po '. Si può pensare a un tavolo come oggetto dinamicamente assegnata; il programma manipola solo riferimenti (o puntatori) a loro. Non ci sono copie nascosti o creazione di nuove tabelle dietro le quinte. Inoltre, non è necessario dichiarare una tabella in Lua; infatti, non vi è alcun modo per dichiarare uno. È possibile creare le tabelle per mezzo di una espressione del costruttore, che nella sua forma più semplice è scritto come {}:

a = {} - creare una tabella e memorizzare il suo riferimento in 'a'
k = "x"
a [k] = 10 - new entry, con il tasto = "x" e valore = 10
un [20] = "grande" - new entry, con key = 20 e il valore = "grande"
stampa (un ["x"]) -> 10
k = 20
stampa (un [k]) -> "grande"
un ["x"] = a ["x"] + 1 - incrementi di entrata "x"
stampa (un ["x"]) -> 11

Una tabella è sempre anonimo. Non vi è alcun rapporto fisso tra una variabile che contiene una tabella e la tabella stessa:

a = {}
un ["x"] = 10
b = a - 'b' si riferisce allo stesso tavolo come `a '
stampa (b ["x"]) -> 10
b ["x"] = 20
stampa (un ["x"]) -> 20
a = nil - ora solo 'b' si riferisce ancora al tavolo
b = nil - ora non ci sono riferimenti a sinistra al tavolo.

Quando un programma non ha riferimenti a un tavolo a sinistra, la gestione della memoria Lua finirà per eliminare la tabella e riutilizzare la sua memoria.
Ogni tabella può memorizzare i valori con diversi tipi di indici e cresce come ha bisogno di ospitare nuove voci:

a = {} - tavolo vuoto
- Creare 1000 nuovi inserimenti
per i = 11.000 fare un [i] = i * 2 estremità
stampa (a [9]) -> 18
un ["x"] = 10
stampa (un ["x"]) -> 10
stampa (un ["y"]) -> nil

Si noti l'ultima riga: come variabili globali, i campi della tabella restituiscono nulla se non vengono inizializzati. Inoltre, come le variabili globali, è possibile assegnare a zero per un campo di tabella per eliminarlo. Questa non è una coincidenza: Lua memorizza le variabili globali nelle tabelle ordinarie. Più su questo argomento nel capitolo 14.
Per rappresentare i record, si utilizza il nome del campo come un indice. Lua supporta questa rappresentazione fornendo a.name come zucchero sintattico per una ["nome"]. Quindi, potremmo scrivere le ultime righe dell'esempio precedente in maniera cleanlier come

ax = 10 - stesso come ["x"] = 10
stampa (ax) - stesso come print (un ["x"])
stampa (aa) - come la stampa (un ["y"])

Per Lua, le due forme sono equivalenti e possono essere mescolati liberamente; ma per un lettore umano, ogni modulo può segnalare un'intenzione diversa.
Un errore comune per i principianti è quello di confondere ascia con un [x]. Il primo modulo rappresenta un ["x"], cioè, una tabella indicizzata dalla stringa "x". La seconda forma è una tabella indicizzata dal valore della variabile x. Vedi la differenza:

a = {}
x = "y"
una [x] = 10 - 10 ha messo in campo "y"
stampa (A [x]) -> 10 - valore del campo "y"
stampa (ax) -> nil - valore del campo "x" (undefined)
stampa (aa) -> 10 - valore del campo "y"
Per rappresentare una matrice convenzionale, è sufficiente utilizzare una tabella con chiavi intere. Non c'è modo di dichiarare la sua dimensione; basta inizializzare gli elementi necessari:

- Leggere 10 linee memorizzandoli in una tabella
a = {}
per i = 1,10 do
a [i] = io.read ()
fine

Quando iterare gli elementi della matrice, il primo indice non inizializzata provocherà nil; è possibile utilizzare questo valore come una sentinella per rappresentare la fine della matrice. Ad esempio, è possibile stampare le linee lette nell'ultimo esempio con il seguente codice:
- Stampare le linee
per i, la linea in ipairs (a) fare
stampa (linea)
fine

La libreria di base Lua offre ipairs, una funzione utile che consente di eseguire iterazioni sugli elementi di un array, a seguito della convenzione che l'array termina al suo primo elemento nullo.
Dal momento che è possibile indicizzare una tabella con qualsiasi valore, è possibile avviare gli indici di un array con qualsiasi numero che ti piace. Tuttavia, è consuetudine in Lua per iniziare con un array (e non con lo zero, come in C) e le librerie standard di attenersi a questa convenzione.

Perché noi in grado di indicizzare una tabella con qualsiasi tipo, quando l'indicizzazione di un tavolo abbiamo le stesse sfumature che si presentano in parità. Sebbene possiamo indicizzare una tabella sia con il numero 0 e con la stringa "0", questi due valori sono differenti (secondo uguaglianza) e quindi indicare posizioni diverse in una tabella. Allo stesso modo, le stringhe "+1", "01" e "1" tutti indicano posizioni diverse. In caso di dubbio circa i tipi effettivi dei vostri indici, utilizzare una conversione esplicita per essere sicuri:

i = 10; j = "10"; k = "10"
a = {}
a [i] = "un valore"
un [j] = "un altro valore"
un [k] = "ancora un altro valore"
stampa (un [j]) -> un altro valore
stampa (un [k]) -> ancora un altro valore
stampa (un [ToNumber (j)]) -> un valore
stampa (un [ToNumber (k)]) -> un valore

È possibile introdurre bug sottili nel programma se non si presta attenzione a questo punto.