Rust/Basic

[Rust Tutorial] 5 - Function

tyoon9781 2024. 11. 17. 15:11

 

 

 


 

Intro

rust의 함수 에 대한 설명과 예제입니다. rust의 함수는 기존 언어와는 좀 다른 점들이 있습니다.

 

  1. return keyword 없이 return할 수 있으며 이 문법이 rust의 기본 문법이다.
  2. borrow 규칙으로 인해 값을 복사하는 함수, 값을 소모하는 함수가 구분된다.
  3. closure 문법 (이건 사실 모든 언어가 다 다르긴 합니다)

function 자체의 input, output에 대한 설명보다는 rust가 가지고 있는 function의 특징 위주로 예제를 작성해 보았습니다.

 

 


Code Example

Rust 1.79.0 (released 2024-06-13) 

fn main(){
    #[allow(warnings)]  // 경고문구 무시할때 사용
    fn no_return_function(x: i32){
        x + 1;          // no return. 세미콜론을 붙이면 return하지 않는다.
    }

    fn func2(x: i32) -> i32 {
        return x + 2;   // return keyword로 return
    }

    fn func3(x: i32) -> i32 {
        // function의 마지막 줄에 ;이 없으면 return으로 간주한다.
        x + 3           // return keyword없이 return.
    }

    fn func_copy(x: i32) -> i32{
        x + 11
    }

    fn func_borrow(x: &mut i32){
        *x += 12;       // return 없이 빌려온 값을 변경하는 함수
    }

    fn func_consum(s: String) -> String{
        s + " world!"   // 소유권 이동. 기존 s는 여기서 소멸
    }

    let x = 0;

    /* [Example] function return */
    println!("{:?}", no_return_function(x)); // ()   함수가 아무것도 return하지 않으면 빈 tuple을 return함
    println!("{:?}", func2(x)); // 2
    println!("{:?}", func3(x)); // 3
    
    /* [Example] scope return */
    let y = {
        let x = 3;
        x + 1   // scope 내에서 return -> y = 4
    };
    println!("{y}");    // 4

    // scope return에서는 return keyword를 사용할 수 없음
    let _y = {
        let _x = 3;
        // [Error] scope 내에서 return keyword을 쓰면 안된다.
        // return x + 1;    // 이 동작은 scope return인지 함수 return인지 알 수 없다.        
    };

    /* [Example] 값 복사, 값 전달, 값 소모 */

    // 값 복사
    let x1: i32= 10;
    let x_copy = func_copy(x1);     // 값을 복사함
    println!("x_copy : {x_copy}");       // 21
    println!("x1 : {x1}");               // 10 
    
    // 값 전달
    let mut x2: i32 = 10;        // mutable한 변수로 선언
    func_borrow(&mut x2);        // [Pointer 개념] : 값의 주소를 전달. 주소의 값을 역참조하여 값을 수정
    println!("x2 : {x2}");       // 22

    // 값 소모
    let s = String::from("hello");
    let new_s = func_consum(s);
    println!("{new_s}");        // hello world!
    // [Error] error[E0382]: borrow of moved value: `s`
    // println!("{s}"); // s는 func_consum에서 소모되었기 때문에 더이상 사용할 수 없다.

    /* 
    값 복사와 값 소모의 차이
    rust에는 Copy trait이라는 개념이 있는데 이것이 구현된 Type은 소모되지 않고 복사됨
    primary type은 Copy trait을 가지고 있음
    그 외의 Type은 Copy trait을 impl하지 않는 이상 전부 값 소모됨
     */

    /* [Example] 익명함수(clousure) */
    // 명시적 type.
    let _closure: fn(u8, u8) -> u8 = |a, b| a + b;
    
    // type inference (타입 추론)을 활용한 Type 생략
    let add = |a, b| a + b;
    let result = add(2, 3);
    println!("add result : {result}");
    
    /* function input에 function 전달 (funtion pointer) */
    fn square(x: i32) -> i32 {
        x * x
    }

    // input type에 함수 input, output type을 명시한다.
    fn apply(f: fn(i32) -> i32, value: i32) -> i32 {
        f(value)
    }

    let result = apply(square, 5);
    println!("square result : {result}");
}

 


 

* reference

 - https://doc.rust-lang.org/book/