هناك بشكل أساسي نوعان من الحلقات:
وكلاهما ممكن في 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.
ويمكن التكرار على أنواع أخرى كثيرة من المجموعات: عناصر مصفوفة، ومحارف سلسلة نصية، ومفاتيح قاموس...
والشرط هو أن تكون المجموعة 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)
الصيغة مشابهة لبايثون، لكنها ليست مطابقة لها. فهناك بعض الاختلاف في حالة تعدد المتغيرات و/أو المصفوفات متعددة الأبعاد، لذا سيُغطى هذا الموضوع بمزيد من التفصيل في مفهوم لاحق.
بصفتها لغة حديثة دالية في معظمها، تملك Julia (بالطبع) أساليب متنوعة للعمل على المجموعات، وليس فقط حلقة صريحة أو حلقة مختصرة داخل استيعاب قائمة.
ستتناول المفاهيم اللاحقة بدائل مثل البث والدوال ذات الرتبة الأعلى.