제어 흐름: 함수와 표현식 핵심 가이드
학습 목표: Rust의 함수 정의 방식과 C#의 메서드를 비교하고, Rust의 가장 특징적인 설계인 표현식(Expression) 기반 문법을 마스터합니다. 이를 통해
if나match구문이 어떻게 삼항 연산자를 대체하고 더 안전한 코드를 만드는지 배웁니다.
1. 함수와 메서드
C#과 달리 Rust는 클래스에 소속되지 않은 **독립 함수(Standalone function)**를 자유롭게 정의할 수 있습니다.
| 비교 항목 | C# 스타일 | Rust 스타일 |
|---|---|---|
| 선언 위치 | 클래스 내부에 정의 (메서드) | 파일 어디서나 정의 가능 (함수) |
| 인자 전달 | ref, out, in | &, &mut (참조 및 빌림) |
| 반환 방식 | return 키워드 필수 | 마지막 줄의 표현식이 자동으로 반환됨 |
| 정적 메서드 | static 키워드 사용 | impl 블록 내에서 self 인자 없이 선언 |
#![allow(unused)] fn main() { // [명시적 return 없이 반환하는 예시] fn add(a: i32, b: i32) -> i32 { a + b // 세미콜론이 없으면 '표현식'으로서 값을 반환합니다. } }
2. 표현식(Expression) vs 문(Statement)
C# 개발자가 Rust에서 처음 직면하는 가장 큰 차이점입니다. Rust에서는 거의 모든 블록이 값을 반환하는 표현식이 될 수 있습니다.
- 문(Statement): 작업을 수행하지만 값을 내놓지 않습니다. 끝에
;가 붙습니다. - 표현식(Expression): 결과값을 산출합니다. 끝에
;를 붙이지 않습니다.
#![allow(unused)] fn main() { // [C# 스타일 (삼항 연산자)] // var message = x > 10 ? "큼" : "작음"; // [Rust 스타일 (if 표현식)] let message = if x > 10 { "큼" } else { "작음" }; // if 블록 자체가 값을 반환 }
3. 반복문과 루프 제어
Rust는 C#의 foreach와 while 외에도 유용한 루프 구문을 제공합니다.
for .. in: 반복자(Iterator)를 순회합니다. C#의foreach와 유사하지만 더 강력합니다. (0..5와 같은 범위 지정 가능)while: 조건이 참인 동안 반복합니다.loop: 무한 루프입니다. 값을 계산하고break를 통해 루프 밖으로 결과를 내보낼 때 매우 유용합니다.
#![allow(unused)] fn main() { // 루프에서 직접 값 반환하기 let result = loop { let val = get_next_value(); if val > 100 { break val; // 루프를 종료하며 값을 result에 대입 } }; }
4. 루프 라벨 (Nested Loops)
중첩된 루프에서 바깥쪽 루프를 한 번에 탈출해야 할 때, C#은 goto나 플래그 변수를 써야 했지만 Rust는 라벨을 지원합니다.
#![allow(unused)] fn main() { 'outer: for x in 0..10 { for y in 0..10 { if x + y > 15 { break 'outer; // 'outer' 라벨이 붙은 루프를 탈출 } } } }
💡 실무 팁: 세미콜론의 마법
함수 마지막 줄에 세미콜론을 찍느냐 마느냐는 사소해 보이지만 의미가 큽니다. 세미콜론을 찍으면 "이 줄에서 작업을 끝낸다(반환값 없음)"는 뜻이고, 찍지 않으면 "이 계산 결과를 반환한다"는 뜻이 됩니다. 이것만 잘 구분해도 많은 컴파일 에러를 예방할 수 있습니다.