web-dev-qa-db-fra.com

retour pour boucle ou boucle extérieure

Aujourd'hui, quelqu'un m'a assisté à une mauvaise utilisation du mot clé return en Java. J'avais écrit une simple boucle for pour valider que quelque chose se trouve dans un tableau. Supposons que array est un tableau de longueur n, voici mon code:

for (int i = 0; i < array.length; ++i) {
    if (array[i] == valueToFind) {
        return true;
    }
}
return false;

Maintenant, quelqu'un m'a dit que ce n'est pas une très bonne programmation car j'utilise l'instruction return dans une boucle et cela entraînerait un dysfonctionnement du ramasse-miettes. Par conséquent, un meilleur code serait:

int i = 0;
while (i < array.length && array[i] != valueToFind) {
    ++i;
}
return i != array.length;

Le problème est que je ne peux pas fournir une explication appropriée de la raison pour laquelle la première boucle for n'est pas une bonne pratique. Quelqu'un peut-il me donner une explication?

26
Daan Pape

Maintenant, quelqu'un m'a dit que ce n'est pas une très bonne programmation car j'utilise l'instruction return dans une boucle et cela entraînerait un dysfonctionnement du ramasse-miettes.

C'est incorrect et suggère que vous devriez traiter les autres conseils de cette personne avec un certain scepticisme.

Le mantra de "avoir une seule déclaration de retour" (ou plus généralement, un seul point de sortie) est important dans les langues où vous devez gérer toutes les ressources vous-même - de cette façon, vous pouvez vous assurer que vous mettez toutes vos code de nettoyage en un seul endroit.

C'est beaucoup moins utile en Java: dès que vous savez que vous devez retourner (et quelle devrait être la valeur de retour), retournez simplement. De cette façon, c'est plus simple à lire - vous n'avez pas à prendre dans le reste de la méthode pour déterminer ce qui va se passer (à part les blocs finally).

58
Jon Skeet

Maintenant, quelqu'un m'a dit que ce n'est pas une très bonne programmation car j'utilise l'instruction return dans une boucle et cela entraînerait un dysfonctionnement du ramasse-miettes.

C'est un tas d'ordures. Tout à l'intérieur de la méthode serait nettoyé à moins qu'il n'y ait d'autres références dans la classe ou ailleurs (une raison pour laquelle l'encapsulation est importante). En règle générale, il est généralement préférable d'utiliser une instruction return simplement parce qu'il est plus facile de déterminer où la méthode se terminera.

Personnellement, j'écrirais:

Boolean retVal = false;
for(int i=0; i<array.length; ++i){
    if(array[i]==valueToFind) {
        retVal = true;
        break; //Break immediately helps if you are looking through a big array
    }
}
return retVal;
6
Mike Thomsen

Il existe des méthodologies dans toutes les langues préconisant l'utilisation d'une seule déclaration de retour dans n'importe quelle fonction. Même si cela peut être impossible dans certains codes, certaines personnes s'efforcent de le faire, cependant, cela peut finir par rendre votre code plus complexe (comme dans plus de lignes de code), mais d'un autre côté, un peu plus facile à suivre (comme dans la logique couler).

Cela ne gâchera en rien la collecte des ordures !!

La meilleure façon de le faire est de définir une valeur booléenne, si vous voulez l'écouter.

boolean flag = false;
for(int i=0; i<array.length; ++i){
    if(array[i] == valueToFind) {
        flag = true;
        break;
    }
}
return flag;
3
jn1kk

Certaines personnes soutiennent qu'une méthode doit avoir un seul point de sortie (par exemple, un seul return). Personnellement, je pense qu'essayer de respecter cette règle produit un code plus difficile à lire. Dans votre exemple, dès que vous trouvez ce que vous cherchiez, retournez-le immédiatement, c'est clair et c'est efficace.

Citant le wiki C2:

La signification originale d'avoir une entrée et une sortie uniques pour une fonction est qu'elle faisait partie de la définition originale de la programmation structurée par opposition au goto SpaghettiCode indiscipliné, et permettait une analyse mathématique claire sur cette base.

Maintenant que la programmation structurée a gagné depuis longtemps, personne ne se soucie plus de cela, et le reste de la page est largement consacré aux meilleures pratiques et à l'esthétique, et non à l'analyse mathématique des constructions de programmation structurée.

2
Óscar López

Le code est valide (c'est-à-dire qu'il compilera et s'exécutera) dans les deux cas.

Un de mes professeurs à Uni nous a dit qu'il n'est pas souhaitable d'avoir des instructions continue, return dans une boucle - for ou while. La raison en est que lors de l'examen du code, il n'est pas immédiatement clair si la longueur totale de la boucle sera exécutée ou si le return ou continue prendra effet.

Voir Pourquoi continuer dans une boucle est-il une mauvaise idée? pour un exemple.

Le point clé à garder à l'esprit est que pour des scénarios simples comme celui-ci, cela n'a pas d'importance (IMO) mais lorsque vous avez une logique complexe déterminant la valeur de retour, le code est "généralement" plus lisible si vous avez une seule instruction de retour au lieu de nombreuses.

En ce qui concerne la collecte des ordures - je ne sais pas pourquoi ce serait un problème.

1
Insectatorious