Itérateur Lua


Un itérateur est un objet qui peut être utilisé pour parcourir tout ou partie des éléments dans un conteneur de bibliothèque de modèles standard. Chaque objet itérateur représente une certaine adresse dans le conteneur

En Lua, un itérateur est une structure qui prend en charge les types de pointeurs, qui peuvent parcourir chaque élément d'une collection.


Générique pour l'itérateur

Générique pour enregistre la fonction d'itération en interne. En fait, il enregistre trois valeurs : la fonction d'itération, la constante d'état et la variable de contrôle.

L'itérateur générique for fournit la paire clé/valeur de la collection. Le format de syntaxe est le suivant :

for k, v in pairs(t) do
    print(k, v)
end

Dans le code ci-dessus, k et v sont des listes de variables (t) ; est une liste d'expressions.

Voir l'exemple suivant :

array = {"Lua", "Tutorial"}

for key,value in ipairs(array) 
do
   print(key, value)
end

Le résultat de l'exécution de code ci-dessus est :

1  Lua
2  Tutorial

Dans l'exemple ci-dessus, nous utilisons la fonction d'itération ipairs fournie par Lua par défaut.

Jetons un coup d'œil au processus d'exécution du normatif pour :

  • Tout d'abord, initialisez et calculez la valeur de l'expression après in. L'expression doit renvoyer ce que le normatif pour require.Trois valeurs : fonction d'itération, constante d'état, variable de contrôle ; tout comme l'affectation à valeurs multiples, si le nombre de résultats renvoyés par l'expression est inférieur à trois, il sera automatiquement rempli avec zéro et l'excédent sera ignoré. .

  • Deuxièmement, appelez la fonction d'itération avec la constante d'état et la variable de contrôle comme paramètres (remarque : pour la structure for, la constante d'état ne sert à rien, récupérez simplement sa valeur lors de l'initialisation et passez-le à la fonction itérative).

  • Troisièmement, attribuez la valeur renvoyée par la fonction itérative à la liste de variables.

  • Quatrièmement, si la première valeur renvoyée est nulle, la boucle se termine, sinon le corps de la boucle est exécuté.

  • Cinquièmement, revenez à la deuxième étape et appelez à nouveau la fonction d'itération

. En Lua, nous utilisons souvent des fonctions pour décrire les itérateurs. Chaque fois que la fonction est appelée, l'élément suivant de la collection est renvoyé. Les itérateurs de Lua incluent les deux types suivants :

  • Itérateur sans état

  • Itérateur multi-états


Itérateur sans état

L'itérateur sans état fait référence à un itérateur qui ne conserve aucun état, donc dans une boucle nous pouvons utiliser des itérateurs sans état pour éviter de créer des fermetures Coût supplémentaire.

À chaque itération, la fonction d'itération est appelée avec les valeurs de deux variables (constante d'état et variable de contrôle) comme paramètres. Un itérateur sans état utilise uniquement ces deux valeurs pour obtenir l'élément suivant.

Un exemple simple typique de ce type d'itérateur sans état est ipairs, qui traverse chaque élément du tableau.

Dans l'exemple suivant, nous utilisons une fonction simple pour implémenter un itérateur et réaliser le carré du nombre 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

Le résultat de sortie de l'exemple ci-dessus est :

1	1
2	4
3	9

Le statut de l'itération comprend La table parcourue (constante d'état qui ne change pas pendant la boucle) et l'indice d'index actuel (variable de contrôle), les ipairs et les fonctions d'itération sont très simples. Nous pouvons l'implémenter dans Lua comme ceci :

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

Lorsque Lua appelle ipairs(a) pour démarrer la boucle, il obtient trois valeurs : la fonction itérative iter, la constante d'état a et la valeur initiale de la variable de contrôle 0, puis Lua appelle iter(a,0) pour renvoyer 1,a ; [1 ] (sauf si a[1]=nil) ; la deuxième itération appelle iter(a,1) pour renvoyer 2, a[2]... jusqu'au premier élément nul.


Itérateurs multi-états

Dans de nombreux cas, les itérateurs doivent enregistrer plusieurs informations d'état au lieu de simples constantes d'état et de variables de contrôle. Le moyen le plus simple consiste à utiliser des fermetures et une autre méthode. consiste à encapsuler toutes les informations d'état dans une table et à utiliser la table comme constante d'état de l'itérateur. Parce que dans ce cas, toutes les informations peuvent être stockées dans la table, la fonction d'itération ne nécessite généralement pas de deuxième paramètre.


Dans l'exemple suivant, nous avons créé notre propre itérateur :

array = {"Lua", "Tutorial"}

function elementIterator (collection)
   local index = 0
   local count = #collection
   -- 闭包函数
   return function ()
      index = index + 1
      if index <= count
      then
         --  返回迭代器的当前元素
         return collection[index]
      end
   end
end

for element in elementIterator(array)
do
   print(element)
end

Le résultat de sortie de l'exemple ci-dessus est :

Lua
Tutorial

Dans le Dans l'exemple ci-dessus, nous pouvons Comme vous pouvez le voir, la fonction de fermeture est utilisée dans elementIterator pour calculer la taille de l'ensemble et afficher chaque élément.