Rust 공식 문서를 참고한 글입니다.
함수
우리가 프로그램의 시작점을 선언할 때 main이라는 함수를 fn을 사용해 정의하며, {} 안에 함수 body를 넣는다는 것을 이미 학습한 바 있다. 변수명처럼 함수 이름도 소문자로 snake case를 사용한다.
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}
함수를 정의하려면 fn 뒤에 함수 이름과 {} 안에 함수의 기능을 작성한다. 중괄호를 통해서 컴파일러에게 함수의 시작과 끝을 알려주는 것이다. 또한 C언어는 함수의 선언 순서가 중요하지만 Rust는 중요하지 않다. 그래서 위 프로그램을 실행하면 오류가 발생하지 않고 제대로 작동된다.
파라미터 Parameter
우리는 함수에 파라미터를 포함해 선언할 수 있다. 파라미터를 사용하면 함수에 어떤 값을 전달할 수 있다. 이때 어떤 값을 인자라고 한다.
이 프로그램은 main에서 another_function 이라는 함수에 매개변수로 5를 전달한다.
fn main() {
another_function(5);
}
fn another_function(x: i32) {
println!("The value of x is: {x}");
}
함수 시그니처에 반드시 매개면수 타입을 명시해주어야 한다. 컴파일러가 해당 매개변수의 타입을 찾아보지 않아도 되고, 오류가 발생하면 유용한 힌트를 제공할 수 있기 때문이다.
State와 Expression
함수의 body 부분에는 일련의 구문으로 구성되고 표현식으로 끝날 수도 있다. 지금까지의 프로그램에는 끝에 표현식이 포함되어 있지 않지만, 표현식은 구문의 일부로 볼 수 있다. Rust는 표현식 기반의 언어이기 때문에 구문과 표현식의 차이를 정확하게 아는 것이 중요하다.
- 구문은 어떤 행동을 수행하는 명령어이며 결과 값을 반환하지 않는다.
- 표현식은 어떤 결과 값을 가진다.
함수의 선언은 구문에 속하고 {}로 감싼 코드 블록도 표현식에 속하는데, 가장 마지막 줄에만 표현식을 포함할 수 있다. 이때 코드 블록 내부 구문을 차례대로 실행하고 마지막 줄에 표현식이 있다면 그 표현식의 결과값이 코드 블록의 결과값이 된다.
fn main() {
let x = (let y = 6);
}
위의 예시는 오류가 발생한다. let y = 6;이라는 구문은 값을 리턴하지 않기 때문에 x에 값이 바인딩 되지 않기 때문이다. C언어나 Ruby 같은 경우, x = y = 6;이라는 구문을 작성할 수 있지만 Rust는 불가능하다.
fn main() {
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {y}");
}
위의 경우 {} 안에 x가 선언되었고 x + 1 이라는 표현식이 있기 때문에 y는 4로 바인딩된다. 여기서 알 수 있는 건, 표현식은 ;(세미콜론)을 사용하지 않는다는 점에서 구문과 차이가 있다.
함수에서 반환값 지정하기
함수에서 반환값을 가지도록 설정할 수 있다. 함수를 선언할 때 -> 를 사용해 타입을 명시하면 반환값을 가지는 함수가 되는 것이다. 타입이 존재하지 않으면 반환값을 가지지 않는다. 함수에서의 반환값이란, 함수 body에서 가장 마지막 줄에 위치하는 표현식이다. 마지막 줄 대신에 return이라는 구문으로 값을 반환할 수 있다. 하지만 암묵적으로는 대부분의 함수는 가장 마지막 줄에 위치하는 표현식을 반환하게 될 것이다.
fn five() -> i32 {
5
}
fn main() {
let x = five();
println!("The value of x is: {x}");
}
five() 함수에는 함수 호출도, 매크로도, 심지어는 let 구문도 없지만 Rust에서는 완벽한 함수다. 함수 선언부에 i32이라는 타입이 명시되어 있고 함수 body에 5라는 숫자 하나만 존재하지만 오류 없이 실행된다.
main 함수를 살펴보자.
첫 번째로 볼 것은 let 구문이다. 새로운 변수 x를 선언하고 five()를 호출해 바인딩한다. five()의 반환값을 x로 바인딩하는 것이다.
let x = five();
두 번째, five 함수에 파라미터가 없고 반환값 타입을 지정한 상태에, 세미콜론 없이 표현식인 5라는 숫자만 존재한다는 것이다. 표현식, 즉 반환값에는 세미콜론을 쓰면 안된다는 점을 눈여겨 봐야 한다.
또 다른 예시를 보자.
fn main() {
let x = plus_one(5);
println!("The value of x is: {x}");
}
fn plus_one(x: i32) -> i32 {
x + 1
}
이 프로그램은 The value of x is: 6 을 반환한다. 만약, plus_one() 함수의 x+1에 세미콜론을 추가하면 오류가 발생할 것이다. 그 이유는 표현식이기 때문에 세미콜론을 붙여 사용할 수 없다.
주석
많은 사람들은 자신의 코드를 읽기 쉬운 코드로 만드려고 노력을 하지만, 어쩔 때는 코드에 대한 설명이 필요한 때도 있다. 이럴 때 주석을 처리해서 개발자들은 읽을 수 있지만 컴파일러는 읽을 수 없도록 할 수 있다.
'언어 > Rust' 카테고리의 다른 글
[Rust] 4-1. 소유권(Ownership) (0) | 2024.09.28 |
---|---|
[Rust] 3-3. 제어문(Control Flow) (0) | 2024.09.26 |
[Rust] 3-1. 변수와 자료형 (1) | 2024.09.25 |
[Rust] 2. 숫자 맞히기 게임 구현(feat.사용자 입출력과 에러 핸들링) (1) | 2024.09.25 |
[Rust] 1. 환경 구축하기 (0) | 2024.09.23 |