পাঠ ৩.৫

Control Flow

Control Flow

Condition-এর উপর ভিত্তি করে code চালানো বা কোনো block বারবার চালানো — এগুলো প্রায় সব language-এর মৌলিক building block। Rust-এ এর জন্য if এবং তিন ধরনের loop — loop, while, for

if expression

src/main.rsrust
fn main() {
    let number = 3;

    if number < 5 {
        println!("condition was true");
    } else {
        println!("condition was false");
    }
}

if keyword + condition + curly bracket-এ body। else optional — না দিলে condition false হলে কিছুই হবে না।

if-এর প্রতিটা branch-কে arm বলে — আগের match-এর arm-এর মতো।

Condition অবশ্যই bool হতে হবে

JavaScript বা Python-এর মতো truthy/falsy concept Rust-এ নেই। condition-এ integer দিলে error:

fn main() {
    let number = 3;

    if number {
        println!("number was three");
    }
}
compile errortext
error[E0308]: mismatched types
 --> src/main.rs:4:8
  |
4 |     if number {
  |        ^^^^^^ expected `bool`, found integer

সঠিক উপায় — explicit comparison:

if number != 0 {
    println!("number was something other than zero");
}

else if

src/main.rsrust
fn main() {
    let number = 6;

    if number % 4 == 0 {
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        println!("number is divisible by 3");
    } else if number % 2 == 0 {
        println!("number is divisible by 2");
    } else {
        println!("number is not divisible by 4, 3, or 2");
    }
}

Rust top-down চেক করে — প্রথম যে condition true হয়, তার block চলে। উদাহরণে number=6 — 4 দিয়ে ভাগ হয় না কিন্তু 3 দিয়ে হয়, তাই "divisible by 3" print হবে। 2 দিয়ে-ও ভাগ হয় কিন্তু সেটা পরীক্ষা করা হবে না।

অনেকগুলো else if থাকলে code untidy হয়ে যায় — তখন match use করা ভালো (Chapter 6-এ)।

if expression — let-এর ডানে

if একটা expression, তাই value দেয় — let-এ assign করা যায়:

src/main.rsrust
fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {number}");
}

দুটো arm-ই same type return করতে হবে — না হলে compile error:

fn main() {
    let condition = true;

    let number = if condition { 5 } else { "six" };

    println!("The value of number is: {number}");
}
compile errortext
error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:4:44
  |
4 |     let number = if condition { 5 } else { "six" };
  |                                 -          ^^^^^ expected integer, found `&str`

কারণ — Rust-কে compile time-এ number-এর type জানতে হবে; integer আর string একসাথে রাখা যায় না।

loop — infinite loop

loop keyword block-কে অনন্তবার চালায় — যতক্ষণ না explicitly থামাও।

src/main.rsrust
fn main() {
    loop {
        println!("again!");
    }
}

Terminal-এ ctrl-C চাপলে interrupt হবে। Code থেকে থামাতে break; পরের iteration-এ যেতে continue

loop থেকে value return

break-এর পরে value দিলে সেটা loop-এর result হয়:

src/main.rsrust
fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    println!("The result is {result}");
}

counter 1 থেকে 10 পর্যন্ত বাড়ে, 10 হলে break counter * 220 return। result-এ 20 bind হয়।

(return পুরো function থেকে exit করে, break শুধু loop থেকে।)

Loop label

নেস্টেড loop-এ break/continue default-এ সবচেয়ে ভেতরের loop-এ কাজ করে। বাইরের loop থামাতে চাইলে label দিতে হয় — single quote দিয়ে শুরু:

src/main.rsrust
fn main() {
    let mut count = 0;
    'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;

        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                break 'counting_up;
            }
            remaining -= 1;
        }

        count += 1;
    }
    println!("End count = {count}");
}
terminal outputtext
count = 0
remaining = 10
remaining = 9
count = 1
remaining = 10
remaining = 9
count = 2
remaining = 10
End count = 2

while loop

condition-based loop-এর জন্য common pattern হলো loop + if + break। Rust-এ এর জন্য shortcut — while:

src/main.rsrust
fn main() {
    let mut number = 3;

    while number != 0 {
        println!("{number}!");

        number -= 1;
    }

    println!("LIFTOFF!!!");
}

condition true থাকা পর্যন্ত body চলে; false হলে exit।

for loop — collection-এর উপর

Array-এর উপর while দিয়ে iterate করা যায়, কিন্তু সেটা error-prone (index ভুল হতে পারে) এবং slow (প্রতিটা iteration-এ bound check):

fn main() {
    let a = [10, 20, 30, 40, 50];
    let mut index = 0;

    while index < 5 {
        println!("the value is: {}", a[index]);

        index += 1;
    }
}

এই কাজের জন্য আসলে for use করা উচিত — সংক্ষিপ্ত, safe, fast:

src/main.rsrust
fn main() {
    let a = [10, 20, 30, 40, 50];

    for element in a {
        println!("the value is: {element}");
    }
}

Array-এর size বদলালে অন্য কিছু change করতে হবে না। for Rust-এ সবচেয়ে use-হওয়া loop।

নির্দিষ্ট সংখ্যক বার চালাতে হলেও for-ই preferred — Range এবং .rev() দিয়ে countdown:

src/main.rsrust
fn main() {
    for number in (1..4).rev() {
        println!("{number}!");
    }
    println!("LIFTOFF!!!");
}

1..4 — 1, 2, 3 (4 inclusive না); .rev() reverse করে — 3, 2, 1।

এই পাঠ থেকে যা শিখলে

  • if/else branching; condition অবশ্যই bool
  • if একটা expression — দুই arm-এ same type থাকলে let-এ assign করা যায়।
  • তিন ধরনের loop — loop (infinite), while (condition), for (collection)।
  • break-এর পর value দিয়ে loop থেকে result return; loop label দিয়ে নেস্টেড loop-এর কোনটা থামবে control।
  • for Rust-এ সবচেয়ে preferred — (1..4).rev()-এর মতো range-ও iterate করা যায়।