Існує фактично два типи циклів:
Обидва можливі в Julia, хоча другий трапляється частіше.
while
Для задач, де кількість повторів циклу заздалегідь невідома, у Julia є цикл while.
Базова форма досить проста:
while condition
do_something()
end
У цьому разі програма повторюватиме цикл, доки condition більше не буде true.
Є два способи достроково вийти з циклу:
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.
Можна перебирати й багато інших типів колекцій: елементи масиву, символи рядка тексту (англ. string), ключі словника...
Вимога одна: колекція має бути 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 (звісно) має безліч способів працювати з колекціями, і не лише явний цикл чи компактний цикл у включенні.
У наступних концепціях ми розглянемо такі альтернативи, як broadcasting і функції вищого порядку.