Upvalues compartilhados entre fechamentos
Entenda vários fechamentos que compartilham o mesmo upvalue e as implicações da mutação.
Upvalues compartilhados entre fechamentos é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.
Compartilhando a mesma variável externa
Dois fechamentos definidos no mesmo escopo podem compartilhar exatamente a mesma célula de variável externa. As alterações feitas por um são percebidas pelo outro.
local function makeGetterSetter()
local value = 0
local function get() return value end
local function set(v) value = v end
return get, set
end
local get, set = makeGetterSetter()
set(42)
print(get()) -- 42Por que ocorre o compartilhamento
Lua não copia as variáveis externas para cada fechamento. Todos os fechamentos criados no mesmo bloco que apontam para a mesma variável local compartilham uma célula de variável externa.
Padrão observador por meio de variável externa compartilhada
Uma variável externa compartilhada pode funcionar como um barramento de mensagens entre vários fechamentos.
local count = 0
local inc = function() count = count + 1 end
local dec = function() count = count - 1 end
local get = function() return count end
inc(); inc(); dec()
print(get()) -- 1Armadilha da variável de loop
Em um loop numeric for, cada iteração cria uma nova variável local de loop; por isso, os fechamentos capturam variáveis externas independentes.
local fns = {}
for i = 1, 3 do
fns[i] = function() return i end
end
print(fns[1](), fns[2](), fns[3]()) -- 1 2 3 (each closure has its own i)Armadilha da variável de loop while
Em um loop while, se o fechamento for criado sobre uma única variável que muda, todos os fechamentos compartilham a mesma variável externa e veem o valor final.
local fns = {}
local i = 0
while i < 3 do
i = i + 1
fns[i] = function() return i end -- all share same i!
end
print(fns[1]()) -- 3 (not 1!)Capturando uma nova variável local
Para capturar valores independentes em um loop while, introduza uma nova variável local dentro do corpo do loop.
local fns = {}
local i = 0
while i < 3 do
i = i + 1
local ci = i -- new local per iteration
fns[i] = function() return ci end
end
print(fns[1]()) -- 1, fns[2]() == 2Padrão de módulo com estado compartilhado
Um módulo pode expor várias funções que compartilham uma tabela de estado privado por meio de variáveis externas.
local function makeStack()
local data = {}
return {
push = function(v) data[#data+1] = v end,
pop = function() local v = data[#data]; data[#data]=nil; return v end,
size = function() return #data end,
}
endAliasing e alteração
Tenha cuidado: todos os fechamentos que fazem referência à mesma variável externa veem imediatamente a mesma alteração. Isso é poderoso, mas pode causar um acoplamento não intencional.
Identidade da variável externa
debug.upvalueid(f, n) retorna a identidade exclusiva da n-ésima variável externa da função f. Dois fechamentos com o mesmo ID de variável externa compartilham a mesma célula.
debug.upvaluejoin
debug.upvaluejoin(f1, n1, f2, n2) faz com que a n-ésima variável externa de f1 compartilhe a mesma célula que a n2-ésima variável externa de f2. Uma ferramenta de baixo nível para depuração.
Padrões práticos
- Pares de obtenção e definição que compartilham uma variável privada.
- Contador de eventos com reinicialização exposta por vários fechamentos.
- Estado de módulo compartilhado entre várias funções da API.
Pergunta sobre variável externa compartilhada
Dois fechamentos get e set são criados no mesmo escopo, e ambos capturam value. Se set(99) for chamado, o que get() retorna?
Recapitulação: variáveis externas compartilhadas
Os fechamentos no mesmo escopo compartilham células de variáveis externas. As alterações ficam imediatamente visíveis para todos os fechamentos que as compartilham. Essa é a base do encapsulamento e do estado de módulos em Lua.
Perguntas Frequentes
A aula “Upvalues compartilhados entre fechamentos” é grátis?
Sim — o texto completo de “Upvalues compartilhados entre fechamentos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.
O que vou aprender em “Upvalues compartilhados entre fechamentos”?
Entenda vários fechamentos que compartilham o mesmo upvalue e as implicações da mutação. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Lua Academy?
Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Upvalues compartilhados entre fechamentos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Lua Academy?
Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O que são upvalues?
- Upvalues compartilhados entre fechamentos
- Funções fábrica e geradores
- Memoização com fechamentos