Quelle est la différence entre loop et while true?

La Rouille tutoriel, et maintenant livre demande, il existe une différence entre while true et loop , mais qu'il n'est pas super important de comprendre, à ce stade.

Si vous avez besoin d'une boucle infinie, vous pourriez être tenté d'écrire ceci:

while true {

cependant, Rust a un mot-clé dédié, boucle, pour gérer ce cas:

loop {

de Rouille de contrôle-analyse des flux de traite cette construction différemment si cela est vrai, puisque nous savons qu'il sera toujours en boucle. Les détails de ce que cela signifie ne sont pas très importants à comprendre à ce stade, mais en général, plus nous pouvons donner d'informations au compilateur, mieux il peut faire avec la sécurité et la génération de code, de sorte que vous devriez toujours préférer boucle lorsque vous prévoyez de boucler à l'infini.

ayant fait un peu de travail de type compilateur, je dois me demander ce que sémantique possible la différence est là, puisqu'il serait trivial pour le compilateur de comprendre les deux sont une boucle infinie.

alors, comment le compilateur les traite-t-il différemment?

20
demandé sur Shepmaster 2015-03-06 07:28:37

3 réponses

Ce fut répondu sur Reddit . Comme vous l'avez dit, le compilateur pourrait cas spécial while true , mais il ne le fait pas. Puisqu'il ne le fait pas, le compilateur n'infère pas sémantiquement qu'une variable non déclarée qui est définie dans une boucle while true doit toujours être initialisée si vous sortez de la boucle, alors qu'il le fait pour une boucle loop :

Il aide également le compilateur raison sur les boucles, par exemple

let x;
loop { x = 1; break; }
println!("{}", x)

est parfaitement valide, tandis que

let x;
while true { x = 1; break; }
println!("{}", x);

ne se compile pas avec" utilisation d'une variable éventuellement non initialisée "pointant vers le x dans le println . Dans le second cas, le compilateur ne détecte pas que le corps de la boucle sera toujours exécuté au moins une fois.

(bien sûr, nous pourrions cas particulier la construction while true pour agir comme loop fait maintenant. Je crois que C'est ce que fait Java.)

18
répondu telotortium 2015-03-06 04:39:45

La première chose à dire est, en termes de performance, ceux-ci sont susceptibles d'être identiques. Alors que la rouille elle-même ne fait rien de spécial avec while true , LLVM fait probablement cette optimisation. Le compilateur Rust essaie de garder les choses simples en déléguant les optimisations à LLVM où il le peut.

en général, plus on peut donner d'informations au compilateur, mieux on peut faire avec la sécurité et la génération de code

alors que certaines expressions constantes peuvent être optimisées par LLVM, la sémantique du langage n'est pas altérée par le fait qu'une expression soit constante ou non. C'est bien, parce que ça aide les humains à mieux raisonner sur le code aussi.

juste parce que true est une expression simple, nous savons qu'elle est constante. Tout comme true != false et [0; 1].len() == 1 . Mais qu'en est-il de num_cpus::get() == 1 ? Je ne sais pas s'il y a des cibles de compilation où ça pourrait être constant, et je ne devrais pas y penser non plus!

l'erreur dans exemple de telotortium serait plus significative si elle était combinée avec du code généré ou des macros. Imaginez une macro qui parfois résulte en une simple expression statique comme true == true , mais parfois renvoie une variable ou appelle une fonction. Parfois le compilateur est capable de s'assurer que la boucle tourne une fois, mais d'autres fois, ça ne peut pas. Dans Rust en ce moment, l'erreur dans cet exemple sera toujours une erreur, quel que soit le code généré pour cette condition. Pas de surprises.

2
répondu Peter Hall 2018-04-14 06:20:49

Quelle est la différence entre loop et while true?

pourriez-vous demander Quelle est la différence entre for et while ? La réponse sera proche de: Qu'est-ce qu'un idiome de programmation?

quand vous écrivez while condition {} , vous dites" bien que la condition soit vraie, faites cela", mais nous pouvons voir que dire" bien que vrai soit vrai, faites cela", est redondant. C'est de là que vient loop , elle peut exprimer les boucles infinies très bien parce que nous disons "boucle". Nous n'avons pas une condition, c'est mieux.

alors, comment le compilateur les traite-t-il différemment?

Je ne peux pas répondre à la question" Comment", mais je suppose que vous voulez savoir"pourquoi". Il permet au compilateur de savoir que cette boucle sera exécutée au moins une fois, comme le do {} while (condition); de C. le compilateur peut utiliser cette information pour produire un meilleur code ou avertissement. De plus, vous serez certain que la boucle sera exécutée là où une boucle while pourrait avoir disparu parce que le compilateur l'optimise. La partie amusante est que Rust interne utilise LLVM, et il semble que LLVM n'a pas une façon d'exprimer boucle infinie, donc il produit bugs dans certains cas.

0
répondu Stargateur 2018-04-09 20:41:20