ํ๋ฆ„ ์ œ์–ด

Rust์—๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์™€๋Š” ๋‹ค๋ฅธ ๋ช‡ ๊ฐ€์ง€ ์ œ์–ด ํ๋ฆ„ ๊ตฌ์กฐ๊ฐ€ ์žˆ์œผ๋ฉฐ ํŒจํ„ด ์ผ์น˜์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • if let ํ‘œํ˜„์‹
  • while let expressions
  • match ํ‘œํ˜„์‹

if let ํ‘œํ˜„์‹

if let ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ’์ด ํŒจํ„ด๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

fn sleep_for(secs: f32) {
    let dur = if let Ok(dur) = std::time::Duration::try_from_secs_f32(secs) {
        dur
    } else {
        std::time::Duration::from_millis(500)
    };
    std::thread::sleep(dur);
    println!("{:?} ๋™์•ˆ ์ž ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.", dur);
}

fn main() {
    sleep_for(-10.0);
    sleep_for(0.8);
}

let else expressions

ํŒจํ„ด์„ ์ผ์น˜์‹œํ‚ค๊ณ  ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์—๋Š” let else๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. โ€˜elseโ€™ ์‚ฌ๋ก€๋Š” ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ๋ฒ—์–ด๋‚˜์•ผ ํ•ฉ๋‹ˆ๋‹ค (return, break ๋˜๋Š” ํŒจ๋‹‰ - ๋ธ”๋ก์˜ ๋‹ค์Œ ์œ„์น˜๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ๋งŒ ์•„๋‹ˆ๋ฉด ๋ฉ๋‹ˆ๋‹ค).

fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
    let s = if let Some(s) = maybe_string {
        s
    } else {
        return Err(String::from("None์„ ๊ฐ€์ ธ์˜ด"));
    };

    let first_byte_char = if let Some(first_byte_char) = s.chars().next() {
        first_byte_char
    } else {
        return Err(String::from("got empty string"));
    };

    if let Some(digit) = first_byte_char.to_digit(16) {
        Ok(digit)
    } else {
        Err(String::from("16์ง„์ˆ˜๊ฐ€ ์•„๋‹˜"))
    }
}

fn main() {
    println!("๊ฒฐ๊ณผ: {:?}", hex_or_die_trying(Some(String::from("foo"))));
}

๋งˆ์ง€๋ง‰์œผ๋กœ, ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋งŒ๋“œ๋Š” loop ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

fn main() {
    let mut name = String::from("Comprehensive Rust ๐Ÿฆ€");
    while let Some(c) = name.pop() {
        println!("character: {c}");
    }
    // (There are more efficient ways to reverse a string!)
}

Here String::pop returns Some(c) until the string is empty, after which it will return None. The while let lets us keep iterating through all items.

This slide should take about 10 minutes.

if-let

  • if let์ด match๋ณด๋‹ค ๋” ๊ฐ„๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ํ•œ๊ฐ€์ง€ ๋ธŒ๋žœ์น˜๋งŒ ํฅ๋ฏธ๋กœ์šด ๊ฒฝ์šฐ). ์ด์™€ ๋‹ฌ๋ฆฌ match์—์„œ๋Š” ๋ชจ๋“  ๋ธŒ๋žœ์น˜๊ฐ€ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ผ๋ฐ˜์  ์‚ฌ์šฉ๋ฒ•์€ Option์„ ์‚ฌ์šฉํ•  ๋•Œ Some ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • match์™€ ๋‹ฌ๋ฆฌ if let์€ ํŒจํ„ด ์ผ์น˜๋ฅผ ์œ„ํ•œ ๋ณดํ˜ธ ์ ˆ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

let-else

์œ„์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ if-let์€ ์ค‘์ฒฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. let-else ๊ตฌ์กฐ๋Š” ์ด ์ค‘์ฒฉ๋œ ์ฝ”๋“œ์˜ ํ‰๋ฉดํ™”๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š”์ง€ ํ•™์ƒ๋“ค์ด ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์–ด์ƒ‰ํ•œ ๋ฒ„์ „์„ ๋‹ค์‹œ ์ž‘์„ฑํ•˜์„ธ์š”.

๋‹ค์‹œ ์ž‘์„ฑ๋œ ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

#![allow(unused)]
fn main() {
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
    let Some(s) = maybe_string else {
        return Err(String::from("None์„ ๊ฐ€์ ธ์˜ด"));
    };

    let Some(first_byte_char) = s.chars().next() else {
        return Err(String::from("got empty string"));
    };

    let Some(digit) = first_byte_char.to_digit(16) else {
        return Err(String::from("16์ง„์ˆ˜๊ฐ€ ์•„๋‹˜"));
    };

    return Ok(digit);
}
}

while-let

  • while let์€ ๊ฐ’์ด ํŒจํ„ด์— ๋งค์น˜๋˜๋Š” ๋™์•ˆ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค.
  • You could rewrite the while let loop as an infinite loop with an if statement that breaks when there is no value to unwrap for name.pop(). The while let provides syntactic sugar for the above scenario.