hyunsu blog

홈강좌Rust 입문·중급 47편 중 12편째

Rust if — 조건은 bool 이어야 하고, if 는 값을 낼 수 있다

목차 · 4
  1. 01if · else if · else
  2. 02조건은 bool 이어야 한다
  3. 03if 는 값을 낸다
  4. 04실습 — 갈래의 타입이 다르면

Rust 의 if 는 조건이 반드시 bool 이어야 한다. 숫자를 그대로 넣으면 E0308 이 난다. else if 로 갈래를 늘리고, if 가 값을 내므로 let label = if … 처럼 결과를 바로 담을 수 있다. 이때 갈래마다 같은 타입을 내야 한다.

01 if · else if · else

기온에 따라 다른 말을 찍어 보자.

rust
fn main() {
    let temp = 31;

    if temp >= 30 {
        println!("hot");
    } else if temp >= 20 {
        println!("warm");
    } else {
        println!("cool");
    }
}
text
   Compiling weather v0.1.0 (~/projects/weather)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/weather`
hot
  • if 조건 { … } 은 조건이 true 일 때만 중괄호 안을 실행한다. 조건에는 괄호를 씌우지 않는다.
  • else if 는 앞 조건이 거짓일 때 다음 조건을 본다. 위에서부터 차례로 보고, 처음으로 참인 갈래 하나만 실행한다.
  • else 는 어느 조건도 참이 아닐 때 실행한다.

31 은 첫 조건 temp >= 30 에서 참이라 hot 만 찍혔다. temp 를 25 로 바꾸면 warm, 10 으로 바꾸면 cool 이 찍힌다.

02 조건은 bool 이어야 한다

다른 언어에서는 if (retries) 처럼 숫자를 조건에 넣으면 0 이 아닐 때 참으로 치기도 한다. Rust 에서는 안 된다.

rust
fn main() {
    let retries = 3;
    if retries {
        println!("retry");
    }
}
text
   Compiling retry v0.1.0 (~/projects/retry)
error[E0308]: mismatched types
 --> src/main.rs:3:8
  |
3 |     if retries {
  |        ^^^^^^^ expected `bool`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `retry` (bin "retry") due to 1 previous error
  1. 무엇 — 타입이 안 맞는다.
  2. 어디 — 3번째 줄의 retries. bool 이 와야 하는데 정수가 왔다.
  3. 고치는 법 — help: 는 없다. 7편의 비교 연산으로 bool 을 만든다. "0 이 아니면" 이라는 뜻이면 if retries != 0 으로 쓴다.

숫자를 몰래 bool 로 바꾸지 않으니, 조건에 무엇을 묻는지 코드에 그대로 드러난다.

03 if 는 값을 낸다

11편에서 세미콜론 없는 식은 값을 낸다고 했다. if 도 식이다. 갈래의 마지막 식이 if 전체의 값이 된다.

rust
fn main() {
    let temp = 31;
    let label = if temp >= 30 { "hot" } else { "fine" };
    println!("{temp} -> {label}");
}
text
   Compiling weather v0.1.0 (~/projects/weather)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/weather`
31 -> hot

if temp >= 30 { "hot" } else { "fine" } 전체가 값 하나가 되어 label 에 담겼다. 다른 언어의 조건 ? 값1 : 값2 를 Rust 는 이렇게 쓴다.

04 실습 — 갈래의 타입이 다르면

if-value 의 else 갈래를 숫자 0 으로 바꿔 보자.

rust
fn main() {
    let temp = 31;
    let label = if temp >= 30 { "hot" } else { 0 };
    println!("{label}");
}
text
error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:3:48
  |
3 |     let label = if temp >= 30 { "hot" } else { 0 };
  |                                 -----          ^ expected `&str`, found integer
  |                                 |
  |                                 expected because of this

이번에는 무엇 줄이 더 구체적이다. if 와 else 의 타입이 서로 맞지 않는다(incompatible types)고 이름을 댄다. 어디 줄은 첫 갈래의 "hot" 이 타입을 &str 로 정했고(expected because of this), else 의 0 이 정수라 어긋났다고 짚는다.

label 이라는 변수 하나에 담길 값이니 타입도 하나여야 한다. 두 갈래를 모두 문자열로 맞추면 된다. 다음 편은 같은 코드를 되풀이하는 loop 와 while 이다.