Il existe essentiellement deux types de boucles :
Les deux sont possibles en Julia, même si la seconde est sans doute plus courante.
while
Pour les problèmes ouverts, où le nombre d'itérations n'est pas connu à l'avance, Julia dispose de la boucle while.
La forme de base est assez simple :
while condition
do_something()
end
Dans ce cas, le programme continue de tourner dans la boucle jusqu'à ce que condition ne soit plus true.
Il existe deux façons de sortir prématurément de la boucle :
break fait sortir de la boucle, l'exécution se poursuivant à la ligne qui suit le end de la boucle.return x arrête l'exécution de la fonction courante et renvoie la valeur de retour x à l'appelant.Avec ces options à disposition, il peut parfois être pratique de créer une boucle « infinie » avec while true ... end, puis de compter sur la détection d'une condition d'arrêt dans le corps de la boucle pour déclencher une instruction break ou un return.
L'illustration la plus simple consiste à parcourir un intervalle.
Si on veut faire quelque chose 10 fois :
for n in 1:10
do_something(n)
end
Si l'itération courante ne remplit pas une condition, il est possible de passer immédiatement à l'itération suivante avec un continue :
for n in 1:10
if is_useless(n)
continue
end
# we decided this iteration could be useful
do_something_slow(n)
end
Sous une forme plus courte, le bloc if peut être remplacé par is_useless(n) && continue.
On peut parcourir bien d'autres types de collections : les éléments d'un tableau, les caractères d'une string, les clés d'un dictionnaire...
La condition est que la collection doit être iterable.
Cela sera expliqué plus en détail dans un concept ultérieur, mais pour l'essentiel, la collection doit pouvoir fournir l'élément suivant lorsqu'on le lui demande, et indiquer que la fin est atteinte et qu'il n'y a plus d'éléments.
Les exemples jusqu'ici parcourent l'intervalle 1:10, où la valeur est aussi l'indice de la boucle.
Plus généralement, on peut avoir besoin de l'indice et pas seulement de la valeur.
Pour cela, on utilise la fonction eachindex(), par exemple for i in eachindex(my_array) ... end.
En Julia, écrire des boucles explicites est généralement moins courant que dans beaucoup de langages traditionnels, car il existe diverses options plus concises.
Un cas particulièrement courant est celui où l'on doit construire un nouveau vecteur à partir des éléments d'une autre collection (vecteur, string, ensemble... il y a de nombreuses possibilités).
Ceux qui aiment les compréhensions de listes en Python seront ravis d'apprendre que Julia peut utiliser une syntaxe similaire.
L'essentiel est de mettre en place une boucle très compacte à l'intérieur d'un vecteur.
La syntaxe la plus simple est de la forme result = [f(x) for x in some_collection].
Avec une boucle traditionnelle, cela s'écrirait :
result = []
for x in some_collection
push!(result, f(x))
end
En option, on peut ajouter une condition à la fin, pour ne sélectionner que les éléments correspondants de la collection :
# multiples of 3
julia> [n^2 for n in 1:10 if n%3 == 0]
3-element Vector{Int64}:
9
36
81
# letters beyond 'h' in the alphabet
julia> [uppercase(c) for c in "Julia" if c > 'h']
3-element Vector{Char}:
'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)
'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)
'I': ASCII/Unicode U+0049 (category Lu: Letter, uppercase)
La syntaxe est similaire à celle de Python, mais pas identique. Il y a quelques divergences pour les variables multiples et/ou les tableaux multidimensionnels, ce sujet sera donc traité plus en détail dans un concept ultérieur.
En tant que langage moderne et majoritairement fonctionnel, Julia dispose (bien sûr) de diverses façons de manipuler des collections, pas seulement d'une boucle explicite ou d'une boucle compacte dans une compréhension.
Des concepts ultérieurs examineront des alternatives telles que la diffusion et les fonctions d'ordre supérieur.