DEV Community

Cover image for Introdução à Linguagem de Programação Lua
Jhonathan Paulo Banczek
Jhonathan Paulo Banczek

Posted on

Introdução à Linguagem de Programação Lua

Lua 5.3

Conceitos Básicos

Lua é uma linguagem de programação multiparadigma, interpretada (executa bytecodes em uma VM baseada em registradores [register-based virtual machine]), tipagem dinâmica e gerenciamento automático de memória com incremental garbage collection.
Lua é uma linguagem escrita em C ANSI.

Dinamicamente tipada: Variáveis em Lua não tem tipos, apenas valores. Não há definição de tipos na linguagem para as variáveis.

Tipos

Todos os valores em Lua são first-class values.

Lua tem 8 tipos básicos: nil, boolean, number, string, function, userdata, thread e table.

nil: tem valor único = nil, que deve ser diferente de qualquer outro valor. Representa ausência de valor.

boolean: tem dois valores, true e false, nil e false tornam uma condição falsa, qualquer outro valor é true.

number: representa tanto números inteiros (integer) quanto números reais (floating-point). (O tipo number usa duas representações internas, ou dois subtypes: int e float, por padrão os dois 64-bit).

string: representa uma sequência imutável de bytes. Também é 8-bit clean, suporta qualquer valor de 8-bit.

function: maneira de representar e manipular funções escritas em Lua e também em C.

userdata: permite que dados em C sejam armazenados um bloco de memória (raw memory) em Lua (apenas pode ser usado pela API C).

thread: representa threads independentes e é usado para implementar corotinas (coroutines ou collaborative multithreading).

table: Implementa associative array, ou seja, um vetor associativo que pode ter como índices não apenas números, mas qualquer valor de Lua, exceto nil. As tabelas podem ser heterogêneas; isto é, eles podem conter valores de todos os tipos (exceto nil). Qualquer chave com valor nulo não é considerada parte da tabela. Por outro lado, qualquer chave que não faça parte de uma tabela tem um valor nulo associado. As tabelas são o único mecanismo de estruturação de dados em Lua; podem ser usadas ​​para representar arrays (vetores e matrizes), lists, symbol tables, sets, records, graphs, trees, hash table, etc.

Elementos Léxicos

Os identificadores em Lua podem ser qualquer sequência de letras, dígitos e sublinhados (underscore), não começando com um dígito e não sendo uma palavra reservada da linguagem.

Lua é uma linguagem case sensitive, ou seja, diferencia letras maiúsculas e minúsculas. Por convenção, deve-se evitar o uso de identificadores com underscore e letra maiúsculas, como por exemplo: _VERSION.

Comentários curtos (uma linha) são feitos com -- (dois hífens), para comentários longos (mais de uma linha) se utiliza dois traços seguidos de dois colchetes de abertura --[[ e dois colchetes de fechamento ]], veja o exemplo abaixo:

-- comentário de uma linha

--[[ comentário
em duas linhas
--]]

Palavras Reservadas

Lua possui 22 palavras reservadas, são elas:

and break do else elseif end
false for function goto if in
local nil not or repeat return
then true until while

Outros tokens da linguagem:

+ - * / % ^ #
& ~ << >> //
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ...

Variável

Existem 3 tipos de variáveis: variáveis globais, variáveis locais e campos da tabela. Todas as variáveis por padrão tem escopo global, a menos que declarada explicitamente como local. Antes da primeira atribuição a uma variável, seu valor é nil.

Criando variáveis:

var1 = 33 -- tipo number, int
var2 = 33.0 -- tipo number, float

ok = true -- tipo boolean, valor verdadeiro
nao_ok = false -- tipo boolean, valor falso

lang = 'Linguagem Lua' -- tipo string, usando aspas duplas
lang = 'Linguagem Lua' -- tipo string, usando aspas simples
-- string com mais de uma linha, se usa colchetes
lang = [[Linguagem de
programação Lua]]

-- table
lista = {1.33, 5.8, 7.8} -- tipo table
lista2 = {1, 5, 10, 1000} -- tipo table
agenda = {pedro = '1234-4321', amanda = '5555-5555'}

Para criar variáveis locais, é necessário usar a palavra reservada local, veja:

local var1 = 44.5
local lista = {1, 4, 5, 6}

Lua permite múltiplas atribuições, do lado esquerdo uma lista de variáveis e do lado direito uma lista de expressões, os elementos são separados por vírgula:

-- a tem o valor 100
-- b tem o valor 200.5
-- c tem o valor 'lua'
a, b, c = 100, 200.5, 'Lua'

-- swap
a, b = 1, 2 -- a = 1, b = 2
a, b = b, a -- a = 2, b = 1

Operações Matemáticas

Lua suporta as seguintes operações aritméticas:

descrição operador exemplo
soma + a + b
subtração - a - b
multiplicação * a * b
divisão / a / b
divisão inteira // a // b
módulo % a % b
exponenciação ^ a ^ b
negativo (operador unário) - -a

Com exceção do operador de exponenciação ^ e de divisão inteira //, os operadores aritméticos funcionam da seguinte maneira:

  • Se os dois operandos são números inteiros (int), a operação é executada sobre números inteiros e o resultado é um número inteiro.

  • Caso contrário, se ambos os operandos forem números ou strings que podem ser convertidos em números, eles serão convertidos em float, a operação será executada seguindo as regras usuais para aritmética de ponto flutuante, e o resultado é um float.

A exponenciação ^ e a divisão / sempre convertem seus operandos em float e o resultado é sempre float.

A divisão inteira // é uma divisão que arredonda pra baixo o número.

Módulo % é o resto da divisão inteira.

Divisão por 0 (zero) não gera uma exceção, mas retorna um valor numérico inf

inf = valor infinito, por exemplo

10/0 -- retorna inf

nan = Not a Number, é um valor especial usado para representar resultados numéricos indefinidos ou não representáveis, por exemplo:

0/0 -- nan

Operadores Relacionais

Lua suporta os seguintes operadores relacionais:

descrição operador exemplo
igualdade == a == a
desigualdade(diferente) ~= a ~= b
menor que < a < b
maior que > a > b
menor ou igual <= a <= b
maior ou igual >= a >= b

Todos os operadores retornam um valor tipo boolean, que pode ser true ou false.

A igualdade == primeiro compara o tipo de seus operandos. Se os tipos forem diferentes, o resultado será falso. Caso contrário, os valores dos operandos são comparados.

Table, userdata e threads são comparados por referência: dois objetos são considerados iguais apenas se forem o mesmo objeto. Sempre que você cria um novo objeto esse novo objeto é diferente de qualquer objeto existente anteriormente.

O operador ~= é a negação da igualdade ==.

As comparações de igualdade == não converte string para number, ou number para string. Sempre irá retornar false, e o operador ~= retorna true:

'0' == 1 -- false
'0' == 0 -- false
'0' ~= 1 -- true
'0' ~= 0 -- true

Seguindo o padrão IEEE 754, o nan é considerado nem menor, nem igual, nem maior que qualquer valor (incluindo ele próprio).

Operadores bit-a-bit

Lua suporta os seguintes operadores bit-a-bit:

descrição operador
bitwise AND &
bitwise OR
bitwise exclusive OR ~
right shift >>
left shift <<
unary bitwise NOT ~

Operadores lógicos

Os operadores lógicos em Lua são and, or, e not.

descrição operador exemplo
e (conjunção) and a and b
ou (disjunção inclusiva) or a or b
não (negado) not not a

Todos os operadores lógicos consideram false e nil como false e qualquer outra coisa como true. As expressões lógicas são avaliadas por curto-circuito (short-circuit evaluation), ou seja, o segundo operando é avaliado apenas se necessário. aqui estão alguns exemplos:

O operador de negação (not) sempre retorna true ou false.

O operador and retorna seu primeiro argumento se esse valor for false ou nil, caso contrário, e retorna seu segundo argumento.

O operador or retorna seu primeiro argumento se esse valor for diferente de nil e false; caso contrário, or retorna seu segundo argumento.

Vejamos os exemplos abaixo com nan, inf e nil:

or:

2 or nil -- 2
nil or 2 -- 2
2 or nan -- 2
nan or 2 -- 2
'Lua' or nil -- 'Lua'
'Lua' or nan -- 'Lua'
'Lua' or inf -- 'Lua'
2 or error() -- 2

and:

2 and nil -- nil
nil and 2 -- 2
2 and nan - nil
nan and 2 -- nil
'Lua' and nil -- nil
'Lua' and nan -- nan
'Lua' and inf -- inf

not:

not 2 -- false
not 'lua' -- false
not nil -- true
not nan -- true
not inf -- true
not not 2 -- true
not true -- false
not false -- true

Precedência

A precedência de operadores em Lua, do maior para o menor:

  • parênteses: (, )
  • exponenciação: ^
  • operadores unários: not, #, -, ~
  • multiplicação: *
  • divisão: /
  • divisão inteira: //
  • módulo: %
  • adição: +
  • subtração: -
  • concatenação de string: ..
  • operadores bit a bit: <<, >>, &, ~, |
  • operadores relacionais: <, >, <=, >=, ~=, ==
  • operadores lógicos: and, or

Os operadores de concatenação .. e exponenciação ^ são associativos-à-direita. E todos os outros operadores binários são associativos-à-esquerda.

Estruturas de Controle

Em Lua temos estruturas de decisão (condicional) e de repetição, semelhante a qualquer outra linguagem de programação. (Lua a partir da versão 5.2 incluiu o comando goto).

Estrutura Condicional

--[[ *exp* é qualquer trecho de código Lua 
que está realizando alguma operação lógica. 
Em uma expressão os valores em Lua como nil 
e false sempre retornam false, qualquer 
outro valor retorna true.
*block* é qualquer trecho de código Lua que 
será executado somente dentro do corpo do condicional
--]]

-- if na mesma linha
if exp then block end

-- ou
if exp then 
  block 
end

-- usando else if (se senão então) na mesma linha
if exp then block elseif exp then block else block end

-- ou
if exp then 
  block
elseif exp then
  block
else
  block
end

Estrutura de Repetição

Para os nossos loops usamos os clássicos while, repeat–until e for.

Usando while e repeat–until

-- while: enquanto *exp* for verdadeira faça
-- no while verifica a *exp* primeiro, depois executa *block*

-- mesma linha
while exp do block end

-- ou
while exp do
  block
end

-- repeat–until, repita até que *exp* seja verdadeira
-- em repeat primeiro executa o bloco e depois verifica a exp

-- mesma linha  
repeat block until exp do

-- ou
repeat
  block
until exp

Usando o for

O loop for em Lua tem duas formas diferentes, uma é um for numérico e outra um for genérico (veja as funções pairs e ipairs na seção sobre funções Embutidas):

for numérico

-- inicial = número inicial
-- limite = número limite
for var = inicial, limite do 
  block
end

-- ou na mesma linha
for var = inicial, limite do block end

Há um terceiro parâmetro opcional: passo (step),

--[[ passo tem um valor padrão de 1, 
pois o loop vai de 1 em 1 iterando 
os elementos do valor inicial ao limite, 
se mudarmos para 2, a iteração será de 2 em 2
--]]

for var = inicial, limite, passo do
    block
end

-- na mesma linha
for var = inicial, limite, passo do block end

-- exemplo
for i = 1, 10, 2 do
    print(i)
end

- ou na mesma linha
for i = 1, 10, 2 do print(i) end

-- saida: 1, 3, 5, 9

-- exemplo, tabuada do 5
for i = 1, 10 do
    print("5 x", i, "=", 5 * i)
end
--[[
saída:
5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
5 x 10 = 50
--]]

Comando break

Para sair (interromper) a execução de um loop usamos o comando break

-- loop infinito
while true do
  print("entrou no loop...")
  break -- interrompe na primeira iteração
  print("nunca será executado")
end

-- outro exemplo
-- observe a linha onde incrementamos nosso 'contador' i
local i = 1
while i < 10 do
    print("entrou no loop")
    if i == 3 then break end
    i = i + 1 -- incremento
end
  print(i) -- 3
--[[ saída:
entrou no loop
entrou no loop
entrou no loop
3
--]]

-- no loop for
for i = 1, 10 do
  print("entrou no loop")
  break -- interrompe
end
print("saiu do loop")

for i = 1, 10 do
  print("entrou no loop")
  if i == 3 then break end
end
print("saiu do loop")

--[[ saída:
entrou no loop
entrou no loop
entrou no loop
saiu do loop
--]]

Funções

Como todos os outros tipos em Lua, function também é first-class-value, isso significa que você pode atribuir uma função a uma variável, passar uma função por parâmetro e retornar um função como valor.

Por padrão as funções são anônimas, você atribui a função a uma variável, como por exemplo:

diga_ola = function() 
  print("olá!") 
end

-- executando
diga_ola() -- imprime "olá"

-- pode ser escrita em uma única linha
diga_ola = function() print("olá!") end

-- Lua fornece syntactic sugar para a definição
-- a função escrita abaixo é equivalente a versão de cima.
function diga_ola()
  print("olá")
end

Ao usar o syntactic sugar, Lua transcreve a função para o formato anônimo. Essas duas formas são equivalentes.

function nome_da_funcao() block end

para

nome_da_funcao = function() block end

Funções podem ter zero ou mais parâmetros e podem ter nenhum ou múltiplos retornos (se usa no final do corpo da função a palavra reservada return), veja:

-- função com 2 parâmetros e 1 retorno
soma = function(a, b)
  local c = a + b
  return c
end

v1 = soma(10, 15) -- v1 = 25

-- 2 parâmetros e 2 retornos
somar_multiplar = function(a, b)
  local c = a + b
  local d = a * b
  return c, d
end

v1, v2 = somar_multiplar(34, 12) -- v1 = 46, v2 = 408

Funções podem receber um número variável de parâmetros(variadic functions), para isso, como último parâmetro use ..., veja no exemplo:

imprimir = function(...)
  print(...)
end

imprimir(1,2,3,4,5,6) -- saída: 1  2  3  4  5  6
imprimir("lua", ".org") -- saída: lua  .org

O escopo de uma função por padrão é global, mas podemos alterar usando a palavra reservada local

local soma = function(a, b, c) return a + b + c end

v = soma(5, 3, 1) -- v = 9 

Tabela

Em Lua existe uma única estrutura de dados: table.

-- criando uma variavel table
a = {} -- vazia

-- usamos o operador unário # para descobrir o tamanho da table
#a -- 0

-- criando com elementos
a = {1, 2, 3, 4, 5, 6} -- funciona como um vetor

a = {1, 2, "Lua", 3, "Linguagem"} -- heterogenea

--[[ quando usado como um vetor, podemos 
acessar via colchetes passando um índice 
--]]
a[1] -- 1
a[2] -- 2
a[3] -- "Lua"
linguagem = a[3] -- linguagem = "Lua"
print(linguagem == "Lua") -- true

--[[ o índice em em Lua começa em 1 
e não em 0 como nas demais linguagens 
--]]
-- podemos colocar outro table como valor
a = {1, 2, "Lua", {"linguagem", "PUC"}, "roberto"}
#a -- tamanho: 5
a[3] -- "Lua"
a[4] -- table: 0x55a93478f110
-- acessando a tabela dentro da tabela
a[4][1] -- "linguagem"
a[4][2] -- "PUC"

a[4][3] -- indice não existe, retorna nil
nome_prof = a[5] -- roberto
print("professor:", nome_prof) -- professor: roberto
a[6] -- nil

--[[ usando table como tabela hash, 
ou (dict em Python), um par de chave-valor (key-value)
--]]

a = {nome = "Roberto", funcao = "professor"}
-- acessamos através da chave nome e operador . (ponto)
a.nome -- "Roberto"
a.funcao -- "professor"
a.outro -- nil

-- podemos acessar por colchetes
a["nome"] -- "Roberto"
a["outro"] -- nil
-- inserindo um novo par chave-valor
a.outro = "Knuth" 
-- ou de outra forma
a["outro"] = "Knuth" 

-- tabelas podem armazenar funções
somar = function(x, y) return x + y end 
a = {5, 7, somar}
a[3](a[1], a[2]) -- 12

-- usando . (ponto)
a = {}
a.valor = 5
a.valor2 = 7
a.f = somar
a.f(a.valor, a.valor2) -- 12

Biblioteca Padrão (Standard Libraries)

Toda linguagem de programação fornece um conjunto de bibliotecas (funções) que estão disponiveis por padrão. A Biblioteca padrão de Lua é implementada diretamente por uma API em C, e é pequena, enxuta, porém, eficiente.

Funções Embutidas

As funções disponíveis por padrão, ou funções embutidas (built-in function) são: assert, collectgarbage, dofile, error, getmetatable, ipairs, load, loadfile, next, pairs, pcall, print, rawequal, rawget, rawlen, rawset, select, setmetatable, tonumber, tostring, xpcall e type. E duas variáveis globais _VERSION e _G.

Funções básicas

assert (v [, message]) levanta um erro (message) caso v seja falso, se v for verdadeiro retorna todos os argumentos:

v, m = assert(2 == 2, 'ok') -- v = true, m = 'ok'

-- v = true, m = 'ok', n = 'ok2', o = 'ok3'
v, m, n, o = assert(2 == 2, 'ok', 'ok2', 'ok3') 

-- levanta um erro
assert(false, "errado!")
stdin:1: errado!
stack traceback:
    [C]: in function 'assert'
    stdin:1: in main chunk
    [C]: in ?

print (···) recebe qual número de parâmetros e os imprime na tela:

print("Olá Lua")
Olá Lua

print("Olá", "Lua")
Olá    Lua

print("Olá", "Lua", "Linguagem")
Olá    Lua Linguagem

-- imprime a referência da tabela
print({linguagem = "Lua"})
table: 0x559004645b70

a = {10, 20, 30}
print(a[3])
30

type (v) retorna uma string com o tipo de v

type(1)
number

type(1.5)
number

type('Lua')
string

type(print)
function

type({})
table

type(nil) -- retorna uma string 'nil' não o valor nil
nil

type(type(nil))
string

type(nan)
nil

> type('')
string

type(type)
function

tostring(v) converte o valor v para uma string

tostring("aa")
aa

tostring(print)
function: 0x559002715db0

tostring("Lua")
Lua

tostring(2020)
2020

tostring(3.14)
3.14

tostring(print) -- string da referência
function: 0x559002715db0

tostring({1, 2, 3}) -- string da referência
table: 0x559004647b80

tonumber (e [, base]) converte o valor e para number. Se o valor não pode ser convertido para number retorna nil.

tonumber("2.3") -- 2.3
tonumber("2,3") -- nil
tonumber("{}") -- nil
tonumber("Lua") -- nil
tonumber({}) -- nil
tonumber(print) -- nil

dofile ([filename]) abre um arquivo Lua e executa seu conteúdo, se o arquivo não estiver no formato correto ocorrerá um erro.

--[[
crie outro arquivo teste.lua, por exemplo e dentro
dele coloque códigos Lua:

soma = function(a,b) return a+b end
a, b = 4, 5
c = soma(a, b)
--]]
-- carrega e executa o arquivo
dofile("teste.lua")
print(a) -- 4
print(b) -- 5
print(c) -- 9
print(soma(3,3)) -- 6

error (message [, level]) leventa um erro com o texto de message, por padrão level = 1

error("Mensagem de Erro")
Mensagem de Erro
stack traceback:
    [C]: in function 'error'
    stdin:1: in main chunk
    [C]: in ?

load (chunk [, chunkname [, mode [, env]]]) carrega um trecho de código Lua, retorna dois valores, o primeiro é uma função o segundo é nil caso não tenha acontecido nenhum erro, ou uma string com a mensagem do erro

f, err = load("x = 2 + 3")
print(x)
nil

f() -- executa o conteúdo x = 2 + 3
print(x)
5

print(err)
nil

-- com erro
f, err = load("x 2 + 3") -- erro sintático
f() -- executa o conteúdo x 2 + 3, levanta um erro
stdin:1: attempt to call a nil value (global 'f')
stack traceback:
    stdin:1: in main chunk
    [C]: in ?

print(err)
[string "x 2 + 5"]:1: syntax error near '2'

loadfile ([filename [, mode [, env]]]) igual o load() porém carrega de um arquivo.

pcall (f [, arg1, ···]) Executa a função f com os argumentos fornecidos de modo protegido. Isso significa que qualquer erro dentro de f não é propagado; em vez disso, o pcall captura o erro e retorna um código de status. Seu primeiro resultado é o código de status (um boolean), que é true se a chamada for bem-sucedida sem erros. Nesse caso, pcall também retorna todos os resultados da chamada, após este primeiro resultado. Em caso de erro, pcall retorna false mais a mensagem de erro.

soma = function(a, b) return a + b end

status, r = pcall(soma, 2, 3)

print(status)
true

print(r)
5

status, r = pcall(soma, "a", 3) -- erro

print(status)
false

print(r) -- string
stdin:1: attempt to perform arithmetic on a string value (local 'a')

-- exemplo com mais de um retorno
soma = function(a, b) return a + b, "Lua" end

status, r, r2 = pcall(soma, 2, 3)
print(status)
true

print(r)
5

print(r2)
"Lua"

-- com erro
status, r, r2 = pcall(soma, "a", 3)
print(status)
false

print(r)
stdin:1: attempt to perform arithmetic on a string value (local 'a')

-- o restante dos parâmetros ficam como nil 
print(r2)
nil

xpcall (f, msgh [, arg1, ···]) Essa função é semelhante à pcall, exceto que define um novo manipulador de mensagens msgh (function).

erro_msg = function() return "Deu errado!" end
soma = function(a, b) return a + b end

status, r = xpcall(soma, erro_msg, 2, 3)
print(status)
true
print(r)
5
-- com erro
status, r = xpcall(soma, erro_msg, "a", 3)
print(status)
false
print(r)
Deu errado!

status, r = xpcall(soma, function() return error() end, "a", 3)
print(status)
false
print(r)
error in error handling

select (index, ···) Se index for um número, retornará todos os argumentos após o índice do número do argumento; um número negativo é indexado a partir do final (-1 é o último argumento). Caso contrário, o índice deve ser a string com '#' e o select retorna o número total de argumentos extras recebidos.

select(3, 1, 2, 3, 4, 5, 6)
3   4   5   6
select(5, 1, 2, 3, 4, 5, 6)
5   6
select('#', 1, 2, 3, 4, 5, 6)
6
select('#', 1, 2, 3)
3
select('#', {1,2,3})
1
select(1, {1,2,3})
table: 0x55a350147720

select(2, {1,2,3}) -- nil

-- usando com vararg
funcao = function(...)
  print (select(1, ...))
  print (select(2, ...))
  print ("quantidade: " .. select('#', ...))
end

funcao(1, 2, 3)
1   2   3
2   3
quantidade:3

funcao(1, 2)
1   2
2
quantidade:2

next (table [, index]) Permite percorrer todos os campos de uma tabela. Seu primeiro argumento é uma tabela (table) e seu segundo argumento é um índice (number) nesta tabela. next retorna o próximo índice da tabela e seu valor associado. Quando chamado com nil como seu segundo argumento, o next retorna o índice inicial e seu valor associado. Quando chamado com o último índice ou com nil em uma tabela vazia, o next retorna nil. Se o segundo argumento estiver ausente, ele será interpretado como nil. Em particular, você pode usar next(t) para verificar se uma tabela está vazia.

tab = {10, 20, 30, 40, 50}
next(tab)
1   10
next(tab, nil)
1   10
next(tab, 1)
2   20
next(tab, 3)
4   40
next(tab, 4)
5   50
next(tab, 5)
nil

rawget (table, index) Obtém o valor real de table[index], sem chamar o metamétodo __index. index pode ser qualquer valor.

tab = {10, 20, 30, 40, 50}
rawget(tab, 1)
10
rawget(tab, 2)
20
rawget(tab, 3)
30
rawget(tab, 4)
40
rawget(tab, 5)
50
rawget(tab, 6)
nil

rawlen(v) Retorna o tamanho do objeto v, pode ser uma table ou uma string, sem invocar o metamétodo __len. Retorna um número inteiro.

rawlen("")
0
rawlen("abc")
3
rawlen("abc123")
6
rawlen({})
0
rawlen({1,2,4})
3
rawlen({1,2,3, "lua"})
4
rawlen({1,2,3, "lua",{}})
5

rawset(table, index, value) Define o valor real da table[index] como value, sem chamar o metamétodo __newindex. table deve ser uma tabela, index qualquer valor diferente de nil e NaN e value qualquer valor de Lua. Esta função modifica e retorna a própria table.

tab = {10, 20, 30}
print(tab[4]) -- nenhum valor no indice 4
nil

tabela = rawset(tab, 4, "Lua")
print(tab[4])
Lua

print(tabela[4])
Lua

tabela = rawset(tab, 1, "Linguagem")
print(tab[1])
Linguagem

print(tabela[1])
Linguagem

rawequal(v1, v2) Verifica se v1 é igual a v2, sem chamar o metamétodo __eq. Retorna um boolean.

tab = {10,20}
t = {10,20}

tab == t
false

rawequal(tab, t)
false
rawequal(tab[1], t[1])
true

tab[1] == t[1]
true

rawequal("Lua", "Lua")
true

f = function() return "Lua" end
rawequal(f, f)
true

f2 = function() return "Lua" end

f == f2
false

rawequal(f, f2)
false

ipairs (t) Retorna 3 valores (um iterator function, a tabela t, e o valor 0). Itera sobre os pares de chave-valor (1, t[1]), (2, t[2]) até o primeiro valor nil.

--- usa no for generico
t = {10, 20, 30, 40}
for k, v in ipairs(t) do
  print(k, v) 
end
1   10
2   20
3   30
4       40

-- inserindo um valor nil no meio da tabela t
t = {10, 20, nil, 30, 40}
for k, v in ipairs(t) do 
  print(k, v) 
end
1   10
2   20
-- note que iterou até o valor nil ser lido e encerrou.

--[[ se tivermos um elemento no formato chave = valor
ele não é lido, é ignorado.
--]]
t = {10, 20, linguagem = "Lua", 30, 40}
> for k, v in ipairs(t) do print(k, v) end
1   10
2   20
3   30
4   40

pairs(t). se t tem um metametodo __pairs, chama-o com t como argumento e retorna os três primeiros resultados da chamada.
Caso contrário, retorna três valores: a função next, a tabela t e nil. pairs itera sobre todas os pares chave-valor.

t = {10, 20, 30}
for k, v in pairs(t) do 
  print(k, v) 
end
1   10
2   20
3       30

t = {10, 20, nil, 30, 40}
> for k, v in pairs(t) do print(k, v) end
1   10
2   20
4   30
5   40
-- com chave-valor no meio da tabela
t = {10, 20, nome = "Lua", 30, 40}
for k, v in pairs(t) do print(k, v) end
1   10
2   20
3   30
4   40
nome    Lua

t = {10, 20, nome = "Lua", 30, 40, autor = "Roberto", lab = "TecGraf"}
for k, v in pairs(t) do print(k, v) end
1   10
2   20
3   30
4   40
autor   Roberto
nome    Lua
lab TecGraf

Outros Recursos

Ficaram de fora dessa introdução:

  • As bibliotecas: coroutine library, package library, string manipulation, basic UTF-8 support, table manipulation, mathematical functions, input and output, operating system facilities, debug facilities.

Esses recursos serão explicados em outros posts, e podem ser conhecidos através do Lua Reference Manual.

Referências e Links importantes

Top comments (0)