English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Iterador (iterator) é um objeto que pode ser usado para percorrer parte ou todos os elementos de um contêiner da biblioteca de templates padrão, cada objeto de iterador representa um endereço determinado no contêiner.
No Lua, o iterador é uma estrutura de tipo de ponteiro que pode percorrer cada elemento da coleção.
O iterador genérico for salva a função de iteração interna, na verdade ele salva três valores: função de iteração, constante de estado, variável de controle.
O iterador genérico for fornece a chave da coleção/Correta de valor, o formato de sintaxe é o seguinte:
for k, v in pairs(t) do print(k, v) end
Nos códigos acima, k, v são listas de variáveis; pairs(t) é uma lista de expressões.
Verifique o seguinte exemplo:
array = {"Google", "w3codebox"} for key, value in ipairs(array) do print(key, value) end
O resultado da execução do código acima é:
1 Google 2 w3codebox
No exemplo acima, usamos a função de iteração padrão fornecida pelo Lua, ipairs.
A seguir, vamos ver o processo de execução do for genérico:
Primeiro, inicialize, calcule o valor da expressão após o in, a expressão deve retornar três valores necessários para o for genérico: função de iteração, constante de estado, variável de controle; como na atribuição de múltiplos valores, se o número de resultados da expressão for insuficiente para três, será automaticamente complementado com nil, e a parte em excesso será ignorada.
Segundo, chame a função de iteração com os parâmetros de constante de estado e variável de controle (atenção: para a estrutura for, a constante de estado não é útil, pois apenas obtém seu valor e passa para a função de iteração no início).
Terceiro, atribua o valor retornado pela função de iteração a uma lista de variáveis.
Quarto, se o primeiro valor retornado for nil, o loop termina, caso contrário, execute o corpo do loop.
Quinto, volte ao passo dois e chame a função de iteração novamente
Em Lua, usamos frequentemente funções para descrever iteradores, onde cada chamada da função retorna o próximo elemento do conjunto. Os iteradores do Lua incluem os seguintes dois tipos:
Iterador sem estado
Iterador de múltiplos estados
Um iterador sem estado é aquele que não mantém nenhum estado, portanto, podemos usar iteradores sem estado no loop para evitar criar closures e custos adicionais.
Em cada iteração, a função de iteração é chamada com os valores dos dois vetores (constantes de estado e variável de controle), um iterador sem estado utiliza esses dois valores para obter o próximo elemento.
Um exemplo típico e simples de iterador sem estado é ipairs, que percorre cada elemento do array.
A seguir, usaremos uma função simples para implementar o iterador, calculando o quadrado do número n:
function square(iteratorMaxCount, currentNumber) if currentNumber < iteratorMaxCount then currentNumber = currentNumber+1 return currentNumber, currentNumber*currentNumber end end for i, n in square,3,0 do print(i, n) end
O resultado da saída do exemplo acima é:
1 1 2 4 3 9
O estado de iteração inclui a tabela percorrida (um estado constante que não muda durante o processo de iteração) e o índice atual (um variável de controle), os funções ipairs e de iteração são muito simples, podemos implementá-las assim no Lua:
function iter(a, i) i = i + 1 local v = a[i] if v then return i, v end end function ipairs(a) return iter, a, 0 end
Quando o Lua chama ipairs(a) para começar o loop, ele obtém três valores: a função de iteração iter, a constante de estado a e o valor inicial do variável de controle 0; então o Lua chama iter(a,0) para retornar 1, a[1](a menos que a[1=nil);A segunda chamada de iteração para iter(a,1) retorna 2, a[2...... até o primeiro elemento nil.
Muitas vezes, os iteradores precisam armazenar várias informações de estado, não apenas constantes de estado simples e variáveis de controle. O método mais simples é usar closure, e há outro método que envolve encapsular todas as informações de estado em uma tabela, usando a tabela como constante de estado do iterador. Neste caso, todas as informações podem ser armazenadas dentro da tabela, então a função de iteração geralmente não precisa de um segundo parâmetro.
Nos exemplos abaixo, criamos nosso próprio iterador:
array = {"Google", "w3codebox"} function elementIterator(collection) local index = 0 local count = #collection -- Função closure return function () index = index + 1 if index <= count then -- Retorna o elemento atual do iterador return collection[index] end end end for element in elementIterator(array) do print(element) end
O resultado da saída do exemplo acima é:
Google w3codebox
Nos exemplos acima, podemos ver que o elementIterator usou a função closure para calcular o tamanho da coleção e imprimir cada elemento.