이 시리즈는 Rust 공식문서를 통해 공부한 흔적임을 밝힙니다.
프로그램의 흐름을 제어하는 대표적인 방법은
특정 조건이 만족하는지 여부에 따라 어떤 코드를 수행하거나
특정 조건이 만족하는 동안 어떤 코드를 반복적으로 수행하는 것이 있다.
조건문의 가장 일반적인 구조에 대해 알아보도록 하자.
이번 시간에는 if
표현식을 사용한 조건문만 다루겠지만
사실 열거형이라는 특별한 자료형과 사용 가능한, 다른 방식의 조건문도 존재한다.
그건 나중에 알아보도록 하자.
if
표현식if
표현식은 조건을 가지며 그 조건의 불리언 값이 true
인 경우에만 실행되는 코드블록을 가진다.
그리고 if
표현식 다음에 선택적으로 사용 가능한 else
표현식은
if
표현식 조건의 불리언 값이 false
인 경우에만 실행되는 코드블록을 가진다.
다른 언어에서는 if
표현식 조건에 숫자, 문자 등 다양한 자료형이 올 수 있기도 하지만
Rust의 if
표현식 조건은 결과값 자료형이 반드시 불리언 자료형이어야 한다.
불리언 값은 양자택일이기 때문에 하나의 if
표현식에는 하나의 else
표현식만 붙을 수 있는데
여러 개의 조건을 연쇄적으로 사용하고 싶다면 else
표현식 대신 else if
표현식으로
이전 조건의 불리언 값이 false
이며 이번 조건의 불리언 값이 true
일 때만 실행되는 코드블록을 사용한다.
peter@hp-laptop:~/rust-practice/chapter03/function_with_return_value$ cd ..
peter@hp-laptop:~/rust-practice/chapter03$ cargo new branches
Created binary (application) `branches` package
peter@hp-laptop:~/rust-practice/chapter03$ cd branches/
peter@hp-laptop:~/rust-practice/chapter03/branches$ vi src/main.rs
src/main.rs
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"); } }
peter@hp-laptop:~/rust-practice/chapter03/branches$ cargo run
Compiling branches v0.1.0 (/home/peter/rust-practice/chapter03/branches)
Finished dev [unoptimized + debuginfo] target(s) in 0.21s
Running `target/debug/branches`
number is divisible by 3
peter@hp-laptop:~/rust-practice/chapter03/branches$
number
의 값을 바꿔가며 실행해보면 다른 결과가 나오는 것을 확인할 수 있다.
if
표현식의 결과값우리는 if
를 표현식이라고 했다.
즉, if
표현식도 어떤 결과값을 가질 수 있다는 것이다.
다른 코드블록이 그랬듯이 if
표현식의 코드블록도 마지막에 표현식을 가질 수 있으며
그것이 이 코드블록, 즉 if
표현식의 결과값이 된다.
여기서 주의할 점은, 모든 분기문의 결과값의 자료형이 동일해야 한다는 것이다.
같은 맥락에서, 어떤 분기는 결과값이 있고 어떤 분기는 없는 형태도 있을 수 없다.
peter@hp-laptop:~/rust-practice/chapter03/branches$ cd ..
peter@hp-laptop:~/rust-practice/chapter03$ cargo new branches_with_retur_value
Created binary (application) `branches_with_retur_value` package
peter@hp-laptop:~/rust-practice/chapter03$ cd branches_with_retur_value/
peter@hp-laptop:~/rust-practice/chapter03/branches_with_retur_value$ vi src/main.rs
src/main.rs
fn main() { let condition = true; let number = if condition { 5 } else { 6 }; println!("The value of number is: {}", number); }
peter@hp-laptop:~/rust-practice/chapter03/branches_with_retur_value$ cargo run
Compiling branches_with_retur_value v0.1.0 (/home/peter/rust-practice/chapter03/branches_with_retur_value)
Finished dev [unoptimized + debuginfo] target(s) in 0.23s
Running `target/debug/branches_with_retur_value`
The value of number is: 5
peter@hp-laptop:~/rust-practice/chapter03/branches_with_retur_value$
러스트에는 세 가지 종류의 반복문이 존재한다.
loop
, while
, for
의 세 가지 반복문에 대해 차례대로 알아보도록 하자.
loop
반복loop
는 코드블록 내의 코드를 무한히 반복한다.
따로 반복 조건을 명시해주지 않는 한 프로그램을 강제 종료할 때까지 이어진다.
프로그램을 강제 종료하는 건 안전한 방법이 아니므로 보통 종료 조건을 명시한다.
종료 조건은 조건문을 사용하여 그 조건에 해당하는 실행문으로 break;
를 사용하면 된다.
우리는 숫자 맞히기 게임을 구현할 때 이를 사용해본 바가 있다.
만약 반복에서 벗어날 때 어떤 결과값을 가지고 싶다면
break
다음에 결과값을 적고 세미콜론을 찍는다.
peter@hp-laptop:~/rust-practice/chapter03$ cargo new repeat_with_loop
Created binary (application) `repeat_with_loop` package
peter@hp-laptop:~/rust-practice/chapter03$ cd repeat_with_loop/
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_loop$ vi src/main.rs
src/main.rs
fn main() { let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; } }; println!("The result is {}", result); }
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_loop$ cargo run
Compiling repeat_with_loop v0.1.0 (/home/peter/rust-practice/chapter03/repeat_with_loop)
Finished dev [unoptimized + debuginfo] target(s) in 0.22s
Running `target/debug/repeat_with_loop`
The result is 20
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_loop$
while
반복어떤 조건을 만족할 때까지 반복하려면 loop
와 break
를 사용하면 된다.
그런데 이렇게 작성할 경우 조건에 대한 가독성이 떨어질 수 있다.
따라서 결과값이 필요한 경우가 아니라면 주로 그것보다는 while
을 통한 반복을 사용한다.
while
은 조건이 true
인 경우에만 반복하며 그것이 false
가 되면 반복을 종료한다.
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_loop$ cd ..
peter@hp-laptop:~/rust-practice/chapter03$ cargo new repeat_with_while
Created binary (application) `repeat_with_while` package
peter@hp-laptop:~/rust-practice/chapter03$ cd repeat_with_while/
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_while$ vi src/main.rs
src/main.rs
fn main() { let mut number = 3; while number != 0 { println!("{}!", number); number -= 1; } println!("LIFTOFF!"); }
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_while$ cargo run
Compiling repeat_with_while v0.1.0 (/home/peter/rust-practice/chapter03/repeat_with_while)
Finished dev [unoptimized + debuginfo] target(s) in 0.56s
Running `target/debug/repeat_with_while`
3!
2!
1!
LIFTOFF!
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_while$
for
반복우리가 반복문을 통해 배열의 각 원소에 접근한다고 가정하자.
이 경우 마지막 인덱스에 도달하였는지 여부를 조건으로 삼아 while
을 사용할 수 있다.
그러나 배열의 길이를 잘못 지정하는 등의 문제가 발생할 여지가 있다.
이런 경우 While
보다 for
을 통한 반복을 사용하는 것이 유리하다.
배열의 각 원소에 대해 반복하는 코드는 다음과 같이 작성할 수 있다.
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_while$ cd ..
peter@hp-laptop:~/rust-practice/chapter03$ cargo new repeat_with_for
Created binary (application) `repeat_with_for` package
peter@hp-laptop:~/rust-practice/chapter03$ cd repeat_with_for/
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_for$ vi src/main.rs
src/main.rs
fn main() { let a = [10, 20, 30, 40, 50]; for element in a.iter() { println!("the value is: {}", element); } }
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_for$ cargo run
Compiling repeat_with_for v0.1.0 (/home/peter/rust-practice/chapter03/repeat_with_for)
Finished dev [unoptimized + debuginfo] target(s) in 0.20s
Running `target/debug/repeat_with_for`
the value is: 10
the value is: 20
the value is: 30
the value is: 40
the value is: 50
peter@hp-laptop:~/rust-practice/chapter03/repeat_with_for$
이렇게 어떤 배열의 원소를 차례대로 접근하는 것 외에도
for
를 통한 반복은 횟수가 정해져 있는 반복에서 유용하다.
for num in min..max
와 같이 구간을 설정하면
num
이 min
에서부터 반복할 때마다 1씩 증가하여 max
미만까지 반복된다.
그리고 (min..max).rev()
를 통해 그 숫자를 역순으로 설정할 수도 있다.
이 포스트의 내용은 공식문서의 3장 5절 Control Flow에 해당합니다.