동작하는 코드
아래 코드를 Rust Playground에서 실행해보세요!
fn greet(name: &str) {
println!("안녕하세요, {name}님!");
}
fn main() {
greet("DaleSchool");
greet("Rust");
}
fn으로 함수를 만들 수 있어요. greet이라는 함수를 만들고, main에서 두 번 호출했어요.
이번에는 값을 돌려주는 함수를 볼게요.
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let result = add(3, 5);
println!("3 + 5 = {result}");
}
-> i32는 "이 함수는 i32 타입의 값을 돌려줘요"라는 뜻이에요. 함수의 마지막 줄에 세미콜론 없이 값을 쓰면 그 값이 반환돼요.
직접 수정하기
아래 코드에서 a + b 뒤에 세미콜론(;)을 붙여보세요. 어떤 에러가 나나요?
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let result = add(10, 20);
println!("결과: {result}");
}
세미콜론을 붙이면 에러가 나고, 빼면 정상 동작해요. 왜 그런지 아래에서 설명할게요!
"왜?" — 표현식과 문장
Rust에서는 표현식(expression) 과 문장(statement) 을 구분해요.
- 표현식: 값을 만들어내요.
3 + 5,a + b같은 것들이에요. - 문장: 값을 만들어내지 않아요. 세미콜론(
;)을 붙이면 문장이 돼요.
fn double(x: i32) -> i32 {
x * 2 // 세미콜론 없음 → 표현식 → 이 값이 반환돼요
}
fn main() {
let result = double(7);
println!("7의 두 배: {result}");
}
함수의 마지막 줄이 표현식이면 그 값이 자동으로 반환돼요. 세미콜론을 붙이면 문장이 되어 아무 값도 돌려주지 않아요.
한 가지 더! 함수의 매개변수(parameter) 에는 반드시 타입을 써야 해요. let에서는 타입 추론이 가능했지만, 함수에서는 생략할 수 없어요.
fn is_even(number: i32) -> bool {
number % 2 == 0
}
fn main() {
println!("4는 짝수? {}", is_even(4));
println!("7은 짝수? {}", is_even(7));
}
심화 학습
return 키워드도 있어요
Rust에도 return 키워드가 있어요. 함수 중간에서 일찍 값을 돌려줄 때 사용해요.
fn check_age(age: i32) -> &'static str {
if age < 0 {
return "나이는 0 이상이어야 해요";
}
"정상 입력이에요"
}
fn main() {
println!("{}", check_age(-1));
println!("{}", check_age(20));
}
마지막 줄에서 반환할 때는 return 없이 세미콜론만 빼면 돼요. Rust에서는 return 없이 쓰는 것이 더 일반적이에요.
반환 타입이 있는 함수에서 세미콜론을 붙이면 에러가 나요.
fn add(a: i32, b: i32) -> i32 {
a + b;
}
fn main() {
println!("{}", add(1, 2));
}
에러 메시지:
error[E0308]: mismatched types
--> src/main.rs:1:32
|
1 | fn add(a: i32, b: i32) -> i32 {
| --- ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail expression
2 | a + b;
| - help: remove this semicolon to return this value
해석: "함수가 i32를 돌려준다고 했는데, 실제로는 아무것도 안 돌려주고 있어요"라는 뜻이에요. 세미콜론을 빼면 a + b가 표현식이 되어 값이 반환돼요.
에러 메시지 마지막 줄을 보세요 — help: remove this semicolon to return this value. 컴파일러가 해결 방법까지 알려주고 있어요!
- 두 개의
i32매개변수를 받아서 큰 쪽을 반환하는max함수를 작성해보세요. (힌트:if a > b { a } else { b }) i32매개변수 하나를 받아서 제곱 값을 반환하는square함수를 작성하고,main에서 호출해보세요.
Q1. 아래 함수의 반환값은 무엇일까요?
fn mystery(x: i32) -> i32 {
x * 3
}
mystery(4)를 호출하면?
- A) 3
- B) 4
- C) 12
- D) 컴파일 에러
Q2. Rust 함수의 매개변수에서 타입을 생략할 수 있나요?
- A) 항상 생략할 수 있다
- B) 절대 생략할 수 없다
- C) 컴파일러가 추론 가능하면 생략할 수 있다
- D)
mut을 붙이면 생략할 수 있다
Q3. 아래 코드의 실행 결과는 무엇일까요?
fn half(x: i32) -> i32 {
x / 2
}
fn main() {
println!("{}", half(7));
}
- A) 3.5
- B) 3
- C) 4
- D) 컴파일 에러