O Metamétodo __index
Parte da seção Lógica e fluxo do Journey de Lua da Coddy. Lição 18 de 54.
Agora que você sabe como associar metatabelas a tabelas, é hora de aprender sobre o metamétodo mais importante: __index. Esse metamétodo controla o que acontece quando você tenta acessar uma chave que não existe em uma tabela.
Normalmente, quando você procura uma chave que não está em uma tabela, Lua retorna nil. Mas, quando uma tabela tem uma metatabela com um campo __index, Lua verifica esse campo. Se __index apontar para outra tabela, Lua procurará a chave nela:
local defaults = {
health = 100,
speed = 10
}
local player = {name = "Alice"}
local meta = {__index = defaults}
setmetatable(player, meta)
print(player.name) -- Saída: Alice
print(player.health) -- Saída: 100Neste exemplo, player tem apenas uma chave name. Quando você acessa player.health, Lua não a encontra em player, então verifica o campo __index da metatable. Como __index aponta para a tabela defaults, Lua procura nela e encontra health = 100.
Isso cria um mecanismo alternativo em que uma tabela pode fornecer valores padrão para outra. A tabela original mantém seus próprios valores, mas quaisquer chaves ausentes são automaticamente procuradas na tabela alternativa.
__index também pode ser uma função. Quando uma chave está ausente, Lua a chama com a tabela e a chave e usa o que ela retornar:
local scores = {alice = 12}
setmetatable(scores, {
__index = function(t, key)
return 0 -- cada nome ausente conta como 0
end
})
print(scores.alice) -- Saída: 12
print(scores.bob) -- Saída: 0Uma tabela fornece valores de fallback fixos; uma função pode calcular um valor para qualquer chave ausente.
Desafio
FácilEscreva uma função createCharacterWithDefaults que receba name e level e retorne uma tabela de personagem com valores padrão para os atributos.
Crie uma tabela de personagem com o nome e o nível fornecidos. Use uma metatabela com __index para fornecer valores padrão para quaisquer atributos ausentes (health, mana, strength).
Lógica:
- Crie uma tabela de valores padrão com as chaves:
health = 100,mana = 50,strength = 10 - Crie uma tabela de personagem com as chaves:
name(o nome fornecido) elevel(o nível fornecido) - Crie uma metatabela com
__indexapontando para a tabela de valores padrão - Anexe a metatabela à tabela de personagem usando
setmetatable() - Retorne a tabela de personagem
Parâmetros:
name(string): O nome do personagemlevel(número): O nível do personagem
Retorno: Uma tabela de personagem com nome, nível e atributos padrão acessíveis por meio da metatabela (tabela)
Experimente você mesmo
function createCharacterWithDefaults(name, level)
-- Escreva o código aqui
end
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica e fluxo
1Iteração avançada de tabelas
Iterando com pairs()Iterando com ipairs()pairs() vs. ipairs()Revisão - Ficha de personagem2Mais funções da biblioteca table
table.concat()Construção de tabelas e unpack()table.sort()Ordenação personalizada com funçõesRevisão - Placar de pontuações máximasPratique por conta própria: Compilador de Lua online