[Rust] 함수(Functions): 선언부터 반환값까지

이 글은 The Rust Programming Language 3.3장 "Functions"을 읽고 정리한 내용이에요. 예제도 이 장의 예제를 바탕으로 했어요.

Rust 프로그래밍의 핵심 구성 요소인 함수를 정리해 볼게요. Rust에서 함수는 어디에나 있고, 이미 써 본 main 함수도 그중 하나예요.

함수 선언과 호출

Rust에서 함수를 새로 만들 때는 fn 키워드를 써요.

명명 규칙: 스네이크 케이스(snake case)

Rust는 함수와 변수 이름을 지을 때 관례적으로 스네이크 케이스를 써요. 모든 글자를 소문자로 쓰고, 단어 사이를 밑줄(_)로 잇는 방식이에요.

예: my_function_name, another_function

코드 구조

함수는 fn 키워드 뒤에 함수 이름과 괄호 ()를 붙여서 정의해요. 실제로 동작하는 코드는 중괄호 {} 안에 써요.

Rust
fn main() {
    println!("Hello, world!");

    another_function(); // 함수 호출!
}

fn another_function() {
    println!("Another function.");
}

참고: another_function이 main 함수보다 뒤에 정의되어 있어도 상관없어요. 호출하는 쪽에서 볼 수 있는 범위(scope) 안에 함수가 정의되어 있으면, Rust는 그 위치가 앞이든 뒤든 신경 쓰지 않아요.

매개변수(Parameters)

함수에 데이터를 넘기고 싶을 때 매개변수를 써요. 매개변수는 함수의 시그니처(signature) 에 선언돼요.

Rust
fn main() {
    print_labeled_measurement(5, 'h');
}

fn print_labeled_measurement(value: i32, unit_label: char) {
    println!("The measurement is: {value}{unit_label}");
}

타입 선언은 필수

함수를 정의할 때 각 매개변수의 타입은 반드시 적어야 해요(예: value: i32). Rust 설계에서 의도한 결정이에요. 덕분에 컴파일러는 함수 밖의 코드를 일일이 보지 않아도 이 함수가 무엇을 받는지 알 수 있고, 더 도움이 되는 에러 메시지를 낼 수 있어요.

구문(Statements)과 표현식(Expressions)

Rust를 처음 접할 때 가장 헷갈릴 수 있는 부분이에요. Rust는 표현식 기반 언어라서 이 둘의 차이를 아는 게 중요해요.

구분설명예시
구문(Statement)어떤 동작을 수행하지만, 값을 반환하지 않음let y = 6;
표현식(Expression)계산해서 결과값을 만들어 냄5 + 6, x + 1

주의할 점

Rust에서는 let x = (let y = 6); 같은 코드가 동작하지 않아요. let y = 6은 구문이라서 돌려줄 값이 없기 때문이에요. 반면 중괄호로 묶인 블록은 그 자체로 표현식이 될 수 있어요.

Rust
let y = {
    let x = 3;
    x + 1 // 세미콜론이 없음에 주목!
};
// y에는 4가 저장됨

위 예시에서 x + 1 뒤에 세미콜론이 없어요. 세미콜론이 없어야 이 값이 블록의 최종 결과값(표현식)이 되어 밖으로 전달돼요.

반환값을 가지는 함수

함수가 작업 결과를 호출한 곳으로 돌려줄 때 써요. 반환할 값의 타입은 화살표(->) 뒤에 적어요.

Rust
fn plus_one(x: i32) -> i32 {
    x + 1 // 세미콜론 없음 = 이 값을 반환하겠다는 뜻
}

fn main() {
    let x = plus_one(5);
    println!("The value of x is: {x}"); // 6 출력
}

암시적 반환과 명시적 반환

  • 암시적 반환: 함수 본문의 마지막 줄에 세미콜론 없이 표현식을 적으면 그 값이 반환돼요. Rust에서는 이 방식을 주로 써요.
  • 명시적 반환: return 키워드를 쓰면 함수 중간에서도 값을 바로 반환하고 끝낼 수 있어요.

x + 1;처럼 세미콜론을 붙이면? 표현식이 구문이 돼요. 그러면 함수는 값이 없다는 뜻의 ()(유닛 타입)를 반환하게 되고, 컴파일러는 error[E0308]: mismatched types(i32를 기대했는데 ()가 왔다는 에러)를 내요.


요약

  • 함수는 fn 키워드로 정의하고, 이름은 스네이크 케이스로 지어요.
  • 매개변수를 선언할 때 타입은 반드시 적어야 해요.
  • 구문(Statement)은 값을 반환하지 않고, 표현식(Expression)은 값을 반환해요.
  • 함수의 마지막 줄에 세미콜론 없이 표현식을 적으면 그게 반환값이 돼요.