J'ai beaucoup travaillé avec Lua ces derniers mois, et j'aime vraiment la plupart des fonctionnalités, mais il me manque encore quelque chose parmi celles-ci:
- Pourquoi n'y a-t-il pas
continue
? - Quelles solutions de contournement y a-t-il?
loops
lua
language-design
Dant
la source
la source
goto
déclaration qui peut être utilisée pour implémenter continue. Voir les réponses ci-dessous.Réponses:
Dans Lua 5.2, la meilleure solution de contournement est d'utiliser goto:
Ceci est pris en charge dans LuaJIT depuis la version 2.0.1
la source
continue
jour réel . Legoto
remplacement n'a pas l'air très beau et a besoin de plus de lignes. De plus, cela ne créerait-il pas de problèmes si vous aviez plus d'une boucle faisant cela dans une fonction, les deux avec::continue::
? Créer un nom par boucle ne semble pas être une bonne chose à faire.La façon dont le langage gère la portée lexicale crée des problèmes avec l'inclusion à la fois
goto
etcontinue
. Par exemple,La déclaration de l'
local a
intérieur du corps de la boucle masque la variable externe nomméea
, et la portée de ce local s'étend à travers la condition de l'until
instruction afin que la condition teste la plus internea
.S'il
continue
existait, il devrait être restreint sémantiquement pour n'être valide qu'une fois que toutes les variables utilisées dans la condition sont entrées dans la portée. C'est une condition difficile à documenter pour l'utilisateur et à appliquer dans le compilateur. Diverses propositions autour de cette question ont été discutées, y compris la réponse simple de refusercontinue
avec lerepeat ... until
style de boucle. Jusqu'à présent, aucun n'a eu de cas d'utilisation suffisamment convaincant pour les inclure dans le langage.Le contournement consiste généralement à inverser la condition qui entraînerait
continue
l'exécution d'un et à collecter le reste du corps de la boucle dans cette condition. Donc, la boucle suivantepourrait être écrit
C'est assez clair et généralement pas un fardeau à moins que vous n'ayez une série d'abattages élaborés qui contrôlent l'opération de boucle.
la source
until...
.goto
dans Lua 5.2. Naturellement,goto
a le même problème. Ils ont finalement décidé que quels que soient les coûts d'exécution et / ou de génération de code à protéger, cela valait la peine d'avoir un flexiblegoto
qui peut être utilisé pour émuler à la foiscontinue
et à plusieurs niveauxbreak
. Vous devrez rechercher les archives de la liste Lua pour les fils pertinents pour obtenir les détails. Puisqu'ils l'ont introduitgoto
, ce n'était évidemment pas insurmontable.local
est une directive réservée au compilateur - peu importe les insructions d'exécution entre l'local
utilisation des variables et l'utilisation des variables - vous n'avez pas besoin de changer quoi que ce soit dans le compilateur pour conserver le même comportement de portée. Oui, cela n'est peut-être pas si évident et nécessite une documentation supplémentaire, mais, pour le répéter, cela nécessite des modifications ZERO dans le compilateur.repeat do break end until true
exemple dans ma réponse génère déjà exactement le même bytecode que le compilateur continuerait, la seule différence est qu'aveccontinue
vous n'auriez pas besoin de syntaxe supplémentaire laide pour l'utiliser.do{int i=0;}while (i == 0);
échoue, ou en C ++:do int i=0;while (i==0);
échoue également ("n'a pas été déclaré dans cette portée"). Trop tard pour changer cela maintenant à Lua, malheureusement.Vous pouvez envelopper le corps de la boucle en plus
repeat until true
, puis l'utiliser à l'do break end
intérieur pour continuer. Naturellement, vous devrez configurer des indicateurs supplémentaires si vous avez également l'intention de vraiment vousbreak
déconnecter.Cela fera une boucle 5 fois, imprimant 1, 2 et 3 à chaque fois.
Cette construction se traduit même par un opcode littéral
JMP
dans le bytecode Lua!la source
luac
résultats sur SO! Avoir un vote positif bien mérité :)Directement du créateur de Lua lui - même :
la source
continue
en Lua, désolé."La première partie est répondue dans la FAQ comme l'a souligné tué .
En ce qui concerne une solution de contournement, vous pouvez envelopper le corps de la boucle dans une fonction et au
return
début de cela, par exempleOu si vous voulez les deux
break
et lacontinue
fonctionnalité, faites effectuer le test par la fonction locale, par exemplela source
collectgarbage("count")
même après vos simples 100 essais et ensuite nous parlerons. Une telle optimisation "prématurée" a évité à un projet à forte charge de redémarrer chaque minute la semaine dernière.Je n'ai jamais utilisé Lua auparavant, mais je l'ai googlé et j'ai trouvé ceci:
http://www.luafaq.org/
Vérifiez la question 1.26 .
la source
Nous pouvons y parvenir comme ci-dessous, cela sautera des nombres pairs
O / P:
la source
Nous avons rencontré ce scénario plusieurs fois et nous utilisons simplement un drapeau pour simuler continuer. Nous essayons également d'éviter l'utilisation des instructions goto.
Exemple: Le code a l'intention d'imprimer les instructions de i = 1 à i = 10 sauf i = 3. En outre, il imprime également "début de boucle", fin de boucle "," si début "et" si fin "pour simuler d'autres instructions imbriquées qui existent dans votre code.
est réalisé en englobant toutes les instructions restantes jusqu'à la fin de la portée de la boucle avec un indicateur de test.
Je ne dis pas que c'est la meilleure approche, mais cela fonctionne parfaitement pour nous.
la source
Lua est un langage de script léger qui se veut le plus petit possible. Par exemple, de nombreuses opérations unaires telles que l'incrément pré / post ne sont pas disponibles
Au lieu de continuer, vous pouvez utiliser goto comme
la source
Encore une fois avec l'inversion, vous pouvez simplement utiliser le code suivant:
la source
Pourquoi n'y a-t-il pas de suite?
Parce que c'est inutile¹. Il y a très peu de situations où un développeur en aurait besoin.
A) Lorsque vous avez une boucle très simple, disons un 1 ou 2 lignes, vous pouvez simplement inverser la condition de la boucle et elle est toujours très lisible.
B) Lorsque vous écrivez un code procédural simple (c'est-à-dire comment nous avons écrit du code au siècle dernier), vous devriez également appliquer une programmation structurée (c'est-à-dire comment nous avons écrit un meilleur code au siècle dernier)
C) Si vous écrivez du code orienté objet, le corps de votre boucle ne doit pas comporter plus d'un ou deux appels de méthode à moins qu'il ne puisse être exprimé en une ou deux lignes (dans ce cas, voir A)
D) Si vous écrivez du code fonctionnel, retournez simplement un appel de fin pour la prochaine itération.
Le seul cas où vous voudriez utiliser un
continue
mot-clé est si vous voulez coder Lua comme si c'était python, ce qui n'est tout simplement pas²².Quelles solutions de contournement y a-t-il?
À moins que A) s'applique, auquel cas il n'y a pas besoin de solutions de contournement, vous devriez faire de la programmation structurée, orientée objet ou fonctionnelle. Ce sont les paradigmes pour lesquels Lua a été conçu, donc vous vous battrez contre le langage si vous faites tout votre possible pour éviter leurs modèles .³
Quelques précisions:
¹ Lua est un langage très minimaliste. Il essaie d'avoir aussi peu de fonctionnalités que possible, et une
continue
déclaration n'est pas une caractéristique essentielle dans ce sens.Je pense que cette philosophie du minimalisme est bien capturée par Roberto Ierusalimschy dans cette interview de 2019 :
² Il semble y avoir un grand nombre de programmeurs qui arrivent à Lua à partir d'autres langues parce que quel que soit le programme pour lequel ils essaient de créer un script, il l'utilise, et beaucoup d'entre eux ne semblent pas vouloir écrire autre chose que leur langue de choix, ce qui conduit à de nombreuses questions telles que "Pourquoi Lua n'a-t-il pas la fonctionnalité X?"
Matz a décrit une situation similaire avec Ruby dans une récente interview :
³ Il existe plusieurs façons de contourner ce problème; certains utilisateurs ont suggéré d'utiliser
goto
, ce qui est une approximation assez bonne dans la plupart des cas, mais devient très moche très rapidement et se rompt complètement avec des boucles imbriquées. L'utilisation degoto
s vous expose également au risque de voir une copie de SICP vous être envoyée chaque fois que vous montrez votre code à quelqu'un d'autre.la source
continue
peut être une fonctionnalité pratique, mais cela ne le rend pas nécessaire . Beaucoup de gens utilisent très bien Lua sans lui, donc il n'y a vraiment aucune raison pour que ce soit autre chose qu'une fonctionnalité intéressante qui n'est essentielle à aucun langage de programmation.