DEV Community

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

Posted on

9 2 1

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

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs