ループには大きく分けて2つの種類があります。
どちらもJuliaで可能ですが、2つ目のほうがよく使われるかもしれません。
whileループループを何回回すかが事前にわからない、終わりの見えない問題のために、Juliaにはwhileループがあります。
基本の形はとてもシンプルです:
while condition
do_something()
end
この場合、プログラムはconditionがtrueでなくなるまでループを回り続けます。
ループを途中で抜ける方法が2つあります:
breakはループを終了させ、実行はループのendの次の行から続きます。return xは現在の関数の実行を停止し、戻り値xを呼び出し元に返します。こうした方法があると、while true ... endで「無限」ループを作っておき、ループ本体の中で停止条件を見つけてbreakやreturnを起こす、という書き方が便利なことがあります。
最も簡単な例は、範囲をループすることです。
何かを10回行いたい場合:
for n in 1:10
do_something(n)
end
現在の繰り返しがある条件を満たさない場合、continueで即座に次の繰り返しへスキップできます:
for n in 1:10
if is_useless(n)
continue
end
# we decided this iteration could be useful
do_something_slow(n)
end
短い形では、ifブロックをis_useless(n) && continueに置き換えることもできます。
他にも多くのコレクション型をループできます:配列の要素、文字列の文字、辞書のキーなどです。
必要なのは、コレクションがiterableであることです。これは後の概念で詳しく説明しますが、要点は、求められたときに次の項目を取り出す方法と、終わりに達してそれ以上項目がないことを示す方法を、コレクションが持っている必要があるということです。
これまでの例では、値がそのままループのインデックスにもなっている範囲1:10をループしていました。
より一般的には、値だけでなくインデックスが必要になることがあります。そのためにはeachindex()関数を使います。例えばfor i in eachindex(my_array) ... endのように書きます。
Juliaでは、明示的なループを書くことは、多くの伝統的な言語よりも少ない傾向があります。より簡潔に書ける方法がいろいろあるからです。
特に一般的なのは、他のコレクション(ベクトル、文字列、集合など、多くの可能性があります)の要素から新しいベクトルを組み立てたい場合です。
Pythonのリスト内包表記が好きな人なら、Juliaでも同様の構文が使えると知って喜ぶでしょう。
要は、ベクトルの中にごくコンパクトなループを組み込むということです。
最もシンプルな構文はresult = [f(x) for x in some_collection]という形です。
伝統的なループで書くと、次のようになります:
result = []
for x in some_collection
push!(result, f(x))
end
必要に応じて、コレクションの中で条件に合う要素だけを選ぶための条件を、末尾に追加できます:
# 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)
構文はPythonと_似ています_が、同一ではありません。複数の変数や多次元配列ではいくつか違いがあるため、この話題は後の概念でより詳しく扱います。
現代的で、ほとんどが関数型の言語であるJuliaには、(もちろん)コレクションを操作する方法がいろいろあります。明示的なループや、内包表記でまとめたループだけではありません。
後の概念では、ブロードキャストや高階関数といった代替手段を見ていきます。