[Rust] 제어 흐름: 조건문과 반복문 완벽 이해하기
프로그램이 조건에 따라 특정 코드를 실행하거나, 특정 조건이 만족되는 동안 코드를 반복해서 실행하도록 만드는 것은 모든 프로그래밍 언어의 기본입니다. Rust에서는 크게 if 표현식과 loop, while, for와 같은 반복문을 사용해 이를 제어합니다.
1. if 표현식 (if Expressions)
if 표현식은 조건에 따라 코드의 실행 경로를 나누는 역할을 합니다. "이 조건이 맞으면 이 코드를 실행하고, 아니면 실행하지 마라"라고 컴퓨터에게 명령하는 것이죠.
기본적인 사용법
가장 기본적인 형태는 if와 else의 조합입니다.
fn main() {
let number = 3;
if number < 5 {
println!("조건이 참입니다");
} else {
println!("조건이 거짓입니다");
}
}
- 조건식:
if키워드 뒤에 오는 조건(위 예시의number < 5)은 반드시 결과가 불리언(bool) 타입이어야 합니다. - Arms: 조건이 참일 때 실행되는
{}블록을 '갈래(arm)'라고 부릅니다. - 엄격한 타입 체크: Rust는 다른 언어(JS, Ruby 등)와 달리 숫자를 자동으로 불리언으로 변환하지 않습니다. 즉,
if number { ... }와 같은 코드는 에러가 발생하며, 반드시if number != 0처럼 명시적으로 비교해야 합니다.
else if로 여러 조건 처리하기
여러 개의 조건을 순차적으로 확인해야 할 때 사용합니다.
fn main() {
let number = 6;
if number % 4 == 0 {
println!("4로 나누어 떨어집니다");
} else if number % 3 == 0 {
println!("3으로 나누어 떨어집니다");
} else {
println!("나머지 경우입니다");
}
}
참고: Rust는 위에서부터 검사하며 가장 먼저 참이 되는 블록 하나만 실행하고 나머지는 건너뜁니다. 조건이 너무 많아진다면 나중에 배울
match를 쓰는 게 더 깔끔합니다.
let 구문에서 if 사용하기
Rust에서 if는 표현식(expression)입니다. 즉, 실행 결과로 값을 내놓는다는 뜻이죠. 이를 이용해 변수에 값을 바로 할당할 수 있습니다.
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("number의 값: {number}");
}
- 타입 일치: 여기서 매우 중요한 점은
if블록과else블록이 반환하는 값의 타입이 같아야 한다는 점입니다. 한쪽은 정수, 한쪽은 문자열이면 컴파일 에러가 발생합니다.
2. 반복문 (Repetition with Loops)
Rust에는 loop, while, for 세 가지 종류의 반복문이 있습니다.
무한 반복 loop
loop는 명시적으로 중단 명령(break)을 내리기 전까지 무한히 반복합니다.
fn main() {
loop {
println!("다시 실행!");
break; // 이 키워드가 있어야 멈춥니다.
}
}
루프에서 값 반환하기
loop는 작업을 재시도한 뒤 그 결과를 밖으로 전달할 때 유용합니다. break 뒤에 값을 적어주면 루프 외부로 그 값이 반환됩니다.
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("결과: {result}"); // 20 출력
}
루프 라벨 (Loop Labels)
여러 루프가 겹쳐있을 때(중첩 루프), 안쪽 루프에서 바깥쪽 루프를 한 번에 종료시키고 싶다면 라벨을 사용합니다. 라벨은 항상 ' (작은따옴표)로 시작합니다.
fn main() {
let mut count = 0;
'counting_up: loop {
let mut remaining = 10;
loop {
if remaining == 9 { break; }
if count == 2 { break 'counting_up; }
remaining -= 1;
}
count += 1;
}
}
조건부 반복 while
조건이 참인 동안에만 루프를 돌리고 싶을 때 사용합니다.
fn main() {
let mut number = 3;
while number != 0 {
println!("{number}!");
number -= 1;
}
println!("LIFTOFF!!!");
}
컬렉션 순회 for
배열이나 리스트 같은 데이터를 하나씩 꺼내어 처리할 때는 for가 가장 안전하고 효율적입니다.
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a {
println!("값: {element}");
}
}
- 안전성:
while문을 써서 인덱스(a[i])로 접근하는 방식은 인덱스 범위를 벗어날 위험이 있지만,for는 컬렉션의 끝을 알아서 파악하므로 안전합니다. - Range 사용: 특정 횟수만큼 반복하고 싶을 때는 범위를 지정하는
(1..4)같은 방식을 씁니다. (.rev()를 붙이면 순서를 뒤집을 수도 있습니다.)
요약
- if: 조건에 따른 분기. 반드시
bool타입을 조건으로 써야 하며, 값을 반환할 수 있음. - loop: 무한 반복.
break와 함께 값을 반환하는 패턴으로 자주 쓰임. - while: 조건이 참일 때만 반복.
- for: 컬렉션 순회에 최적화된 가장 안전하고 권장되는 방식.