ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Rust] 4. ownership(2).함수와 ownership
    rust 2023. 1. 28. 16:01
    반응형

    Ownership Rule

     - value 는 owner 로 불리는 variable을 가지고 있다.

     - value의 owner에 해당하는 variable 은 하나만 존재한다.

     - owner 에 해당하는 varialble 이 scope 을 벗어나면 value는 drop 된다.

     

    함수와 Ownership

    함수에 인자로 전달해주는경우 스택에 저장된 데이터는 copy되서 전달 되지만 heap 데이터 같은 경우는 ownership이 함수로 move 되면서 기존 변수는 유효하지 않게 된다.

    fn main() {
        let x = 5;
     	func(x);  
        println!("{}",x); // x 는 copy한값이 함수에 전달되었기 때문에 여전히 유효하다.
    
        let s = String::from("hello"); 
        func2(s);
        println!("{}",s); // s 는 함수에 전달된 이후 유효하지 않아 컴파일에러가 난다.
    }

     

     

     

    기본적으로 함수는 변수에 할당하는것과 같이 ownership 이 move 하게 되며 따론 반환해주지 않는 다면 그변수는 소멸된다.

    아래와 같이 인자를 같이 return 해줌으로써 다시 사용하게 할수도 있지만 꽤나 불필요한 작업이 동반된다.

    fn main() {
        let s1 = String::from("hello");
    
        let (s2, len) = calculate_length(s1);
    
        println!("The length of '{}' is {}.", s2, len);
    }
    
    fn calculate_length(s: String) -> (String, usize) {
        let length = s.len(); // len()함수는 문자열의 길이를 반환합니다.
    
        (s, length)
    }

    위와 같은 작업 대신에 인자로 변수를 그대로 넘겨주는것이 아니라 참조자(reference)를 넘겨주면 기존 변수가 move 로 인하여 ownership을 잃지 않으면서 이후에도 사용할수 있는데 이러한 동작을 borrowing 이라고 한다.

     

    여기서 원칙 3을 다시보면 좋은데

    - owner 에 해당하는 varialble 이 scope 을 벗어나면 value는 drop 된다.

     

    참조자를 인자로 받는 경우 참조자는 값을 참조하지만 소유하지는 않는다. 즉 owner 가 아니게 된다 따라서 함수의 scope을 벗어나더라도 따로 drop 시킬대상이 아니게된다. 아래의 예시를 보자

    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    
    fn calculate_length(s: &String) -> usize { // s는 String의 참조자입니다
        s.len()
    }

    calc 함수는 인자로 &s1 참조자를 받았고 이는 ownership을 가지고 있는 owner가 아니다 따라서 calc 함수가 종료된 이후에 drop이 될 value 가 존재하지 않게된다.

    다시 더 위의 예 에서 s1을 받은경우 s1이 owner 였기 때문에 함수가 값을 반환하면서 scope 에서 벗어날때 s1의 value 가 drop 되었던 상황과 비교하면 좋을것 같다.

     

    추가로 알아둬야할 점은 변수는 기본적으로 mut 키워드를 붙여주지 않으면 immutable 하다. 이러한 특징은 참조자 역시 마찬가지이며 mut키워드를 이용하면 mutable references 로도 사용할수 있다.

    fn main() {
        let mut s = String::from("hello");
    
        change(&mut s);
    }
    
    fn change(some_string: &mut String) {
        some_string.push_str(", world");
    }

    이때 제한 사항이 하나 있는데 참조자가 동일 scope 내에 하나이상 존재하는 경우 data race를 유발방지를 위하여 mutable reference 생성이 불가능 하다.

     

    Reference Rule

    1. 하나의 가변참조자 혹은 다수의 불변 참조자들 로 존재할수있다.

    2. 참조하고자 하는 value 가 유효한 범위 여야 한다.

    'rust' 카테고리의 다른 글

    [Rust] 5. struct에 대하여  (0) 2023.01.31
    [Rust] 4.ownership(3). slice  (0) 2023.01.28
    [Rust] 4. ownership(1). ownership, 변수와 ownership  (0) 2023.01.28
    [Rust] 3. 변수, 데이터타입  (0) 2023.01.26
    [Rust] 2.programing guessing game  (0) 2023.01.25
Designed by Tistory.