«حلقه» یک «ساختار کنترلی» است که اجازه میدهد کد بر اساس یک «شرط» مشخص بارها اجرا شود.
حلقهی While یک ساختار کنترلی است که اجازه میدهد کد بر اساس یک شرط مشخص بارها اجرا شود. کدی که درون حلقهی While قرار دارد، تا زمانی که شرط «درست» ارزیابی شود، به اجرا ادامه میدهد. از حلقههای While معمولاً زمانی استفاده میشود که تعداد تکرارها از پیش معلوم نیست؛ همچنین میتوان از آنها در هر موقعیتی که به حلقه نیاز باشد استفاده کرد.
شرط پیش از اجرای کد درون حلقه ارزیابی میشود؛ یعنی اگر شرط «غلط» باشد، کد درون حلقه هرگز اجرا نمیشود.
i = 0
while i < 3
puts i
i += 1
end
# Output:
# 0
# 1
# 2
وقتی میخواهید روی یک رشته پیمایش کنید، میتوانید روی طول رشته حلقه بزنید.
str = "Hello"
i = 0
while i < str.size
puts str[i]
i += 1
end
# Output:
# H
# e
# l
# l
# o
حلقههای Until مانند حلقههای While کار میکنند، با این تفاوت که کد درون حلقه تا زمانی که شرط به «درست» ارزیابی شود به اجرا ادامه میدهد.
این همان تفاوت میان if و unless است.
i = 0
until i == 3
puts i
i += 1
end
یک خطای رایج در حلقههای While، گرفتار شدن در «حلقهی بیپایان» است که هرگز پایان نمییابد. یک حلقهی بیپایان میتواند ناشی از شرطی باشد که هرگز به «درست» یا «غلط» ارزیابی نمیشود. این مشکل معمولاً ناشی از خطای برنامهنویس است؛ برای مثال، فراموش کردن افزایش متغیر حلقه. اما گاهی یک حلقهی بیپایان روشنترین راه برای پیادهسازی منطق برنامه است. یا گاهی حلقه زدن تا ابد ضروری است؛ برای مثال، یک سرور HTTP منتظر اتصال ورودی میماند، آن را پردازش میکند و سپس منتظر اتصال بعدی میماند.
میتوان از «کلیدواژه»ی break برای خروج زودهنگام از حلقه استفاده کرد.
این کار زمانی راحت است که بخواهید تحت شرایط خاصی زودتر از حلقه خارج شوید.
i = 0
while i <= 3
puts i
i += 1
if i == 2
break
end
end
# Output:
# 0
# 1
میتوان از کلیدواژهی next برای پرش به تکرار بعدی حلقه استفاده کرد.
این کار زمانی راحت است که بخواهید از تکرارهای خاصی از حلقه صرفنظر کنید.
i = 0
while i <= 3
i += 1
if i == 2
next
end
puts i
end
# Output:
# 1
# 3
نوع متغیر میتواند در حین اجرای حلقه متفاوت باشد.
در مثال زیر، نوع a برابر Int32 | String است، چون در بخش اول حلقه میتواند Int32 یا String باشد.
متغیر a تنها در بخش اول حلقه نوع Int32 | String را خواهد داشت، چون هنگام شروع حلقه مقدار Int32 را نگه میدارد و در تکرار دوم مقدار String را نگه میدارد.
این سیستم چندنوعی بعداً بهتفصیل توضیح داده خواهد شد.
اما چون مطمئن هستیم که بخش دوم حلقه فقط String را نگه میدارد، نوع a در بخش دوم حلقه String است.
در زمان اجرا، هرگز بهطور همزمان Int32 و String را نگه نمیدارد.
i = 0
a = 4
while i < 3
p typeof(a)
# => Int32 | String
a = "4"
p typeof(a)
# => String
i += 1
end
در Crystal، آخرین عبارت در یک متد مقدار خود را برمیگرداند.
با این حال، گاهی لازم است مقداری را پیش از آخرین عبارت برگردانید.
برای این کار میتوانید از کلیدواژهی return استفاده کنید که مقدار عبارت بعدی را برمیگرداند.
کدی که پس از کلیدواژهی return نوشته شود، اجرا نخواهد شد.
def speed_limit(road_number)
if road_number == 1
return 50
puts "This will not be executed"
elsif road_number == 2
return 80
puts "This will not be executed"
end
100
end
p speed_limit(1) # => 50
p speed_limit(2) # => 80
p speed_limit(3) # => 100
وقتی آخرین عبارت در یک متد همان مقداری است که باید برگردانده شود، باید کلیدواژهی return را حذف کرد.
در این تمرین با حسابهای پسانداز کار میکنید. هر سال، موجودی حساب پسانداز شما بر اساس نرخ سود آن بهروزرسانی میشود. نرخ سودی که بانک به شما میدهد به مقدار پول در حساب شما (یعنی موجودی آن) بستگی دارد:
1000 دلار.1000 دلار و کمتر از 5000 دلار.5000 دلار.چهار کار پیش رو دارید که هر کدام به موجودی و نرخ سود آن میپردازد.
متد SavingsAccount.interest_rate() را پیادهسازی کنید که یک موجودی را به عنوان آرگومان میگیرد.
این متد باید نرخ سود را برای موجودی دادهشده برگرداند.
SavingsAccount.interest_rate(200.75)
# => 0.5
متد SavingsAccount.interest() را پیادهسازی کنید که یک موجودی را به عنوان آرگومان میگیرد.
این متد باید سود مربوط به موجودی دادهشده را برگرداند.
SavingsAccount.interest(200.75)
# => 1.00375
متد SavingsAccount.annual_balance_update() را پیادهسازی کنید که یک موجودی را به عنوان آرگومان میگیرد.
این متد باید موجودی را پس از یک سال برگرداند.
SavingsAccount.annual_balance_update(200.75)
# => 201.75375
متد SavingsAccount.years_before_desired_balance() را پیادهسازی کنید که یک موجودی و یک موجودی هدف را به عنوان آرگومان میگیرد.
این متد باید تعداد سالهایی را که برای رسیدن به موجودی هدف لازم است، برگرداند.
balance = 200.75
target_balance = 214.88
SavingsAccount.years_before_desired_balance(balance, target_balance)
# => 14
وقتی سود ساده به موجودی اصل اعمال میشود، موجودی در نرخ سود ضرب میشود و حاصلضرب این دو، مقدار سود است.
از طرف دیگر، سود مرکب با اعمال سود به صورت دورهای محاسبه میشود. در هر بار اعمال، مقدار سود محاسبه و به موجودی اصل اضافه میشود، به طوری که محاسبات سود بعدی روی موجودی اصل بزرگتری انجام میشوند.