[Rust] mutable reference 원칙

0xDave·2022년 6월 25일
0

Rust

목록 보기
8/16
post-thumbnail

Mutable reference 원칙

  1. 한 시점에 오직 하나의 mut ref 만 존재해야 한다.
  2. 컴파일러는 한 문장이 아닌 코드 전체 문맥에 따라 mut ref의 갯수를 결정한다.
  3. immutable reference는 무수히 많아도 상관 없다.
  4. immut ref과 mut ref은 공존할 수 없다.
    (immut ref이 참조하는 값이 mut ref으로 수정하기 전인지 후인지 판단할 수 없기 때문)

예제코드


struct Point { x: i32, y: i32, z: i32 }

fn main() {
    let mut point = Point { x: 0, y: 0, z: 0 };

    let borrowed_point = &point;
    let another_borrow = &point;

    // Data can be accessed via the references and the original owner
    println!("Point has coordinates: ({}, {}, {})",
                borrowed_point.x, another_borrow.y, point.z);

    // Error! Can't borrow `point` as mutable because it's currently
    // borrowed as immutable.
    // let mutable_borrow = &mut point;
    // TODO ^ Try uncommenting this line

    // The borrowed values are used again here
    println!("Point has coordinates: ({}, {}, {})",
                borrowed_point.x, another_borrow.y, point.z);

    // The immutable references are no longer used for the rest of the code so
    // it is possible to reborrow with a mutable reference.
    let mutable_borrow = &mut point;

    // Change data via mutable reference
    mutable_borrow.x = 5;
    mutable_borrow.y = 2;
    mutable_borrow.z = 1;

    // Error! Can't borrow `point` as immutable because it's currently
    // borrowed as mutable.
    // let y = &point.y;
    // TODO ^ Try uncommenting this line

    // Error! Can't print because `println!` takes an immutable reference.
    // println!("Point Z coordinate is {}", point.z);
    // TODO ^ Try uncommenting this line

    // Ok! Mutable references can be passed as immutable to `println!`
    println!("Point has coordinates: ({}, {}, {})",
                mutable_borrow.x, mutable_borrow.y, mutable_borrow.z);

    // The mutable reference is no longer used for the rest of the code so it
    // is possible to reborrow
    let new_borrowed_point = &point;
    println!("Point now has coordinates: ({}, {}, {})",
             new_borrowed_point.x, new_borrowed_point.y, new_borrowed_point.z);
}


위 예제에서 원칙뿐만 아니라 추가적으로 기억해야 할 것은 첫 번째 부분이다.

    let mut point = Point { x: 0, y: 0, z: 0 };

    let borrowed_point = &point;
    let another_borrow = &point;

&point 값을 할당한 borrowd_pointmut ref point 가 아니다. 즉, 이미 앞에서 mut으로 지정한 변수에 ref를 한다는 것은 변수만 따로 가져와서 ref를 한다는 것이지 mut까지 같이 가져오는 것이 아니다. ref와 mut을 따로 봐야하며 헷갈리지 않도록 주의하자.

profile
Just BUIDL :)

0개의 댓글