본문 바로가기

Rust/기타 팁

C++ 참조자 처럼 사용하기(?)

[1. 개요]

C++ 참조자와 비슷한 개념이 rust 에도 있다고 생각하는데, 

C++ 참조자와 같은 패턴을 rust 에서도 사용하려니, 잘 안되서 정리해본다.


[2. 간단한 예제]

fn main() {
    let mut myarray: [u32; 4] = [0; 4];
    println!("{:?}", myarray);

    myarray[0] = 1; // 직접 접근하여 값을 수정.
    println!("{:?}", myarray);

    let rv = &myarray[0]; // 0번째 원소의 참조자, 읽기만 가능함.
    println!("{:?} {:?}", rv, *rv);

    let rv = &mut myarray[1]; // 1번째 원소의 mutable 참조자.
    // rv = 2; // **compile error** 
               // rv 자체는 immutable 하여 수정이 불가능하다. 
               // int * const ptr; 
               // ptr 이 가리키는 대상을 변경할 수 없다.
                
    *rv = 2;   // const int * ptr;
               // ptr 이 가리키는 대상은 변경할 수 있지만,
               // 가리키는 대상의 값을 변경 할 수는 없다. 
    println!("{:?} {:?}", rv, *rv);
    println!("{:?}", myarray);
}

[3. 조금 심화 예제]

fn main() {
    let mut myarray: [Option<u32>; 4] = [None; 4]; 
    println!("{:?}", myarray);

    myarray[0] = Some(1); // 직접 접근하여 값을 수정.
    println!("{:?}", myarray);

    let rv = &myarray[0]; // 읽기만 가능함.
    println!("{:?} {:?}", rv, *rv);

    let rv = &mut myarray[1];
    // rv = &mut myarray[2]; // compile error, rv is immutable.
    *rv = Some(2); 
    println!("{:?} {:?}", rv, *rv);

    let mut rv = &mut myarray[2];
    println!("{:?}", rv);
    rv = &mut myarray[3]; // rv 의 참조 대상을 변경한다. rv 가 mutable 하기 때문에 가능하다.
    *rv = Some(4);        // rv 의 참조 대상의 값을 변경한다. rv 가 참조하는 대상이 mutable 하기 때문에 가능하다.
    println!("{:?}", myarray);
}

[4. 심화 예제]

fn main() {
    // let mut myarray: [Option<Box<u32>>; 4] = [None; 4]; // Compile error, the trait bound `Box<u32>: Copy` is not satisfied
    // Box<u32> 가 Copy trait 을 구현하지 않으므로, 복사할 수 없다.
    // 
    // 따라서 아래와 같이, 길이에 맞게 직접 타이핑 하던가, 아니면...
    // let mut myarray: [Option<Box<u32>>; 4] = [None, None, None, None];
    let mut myarray: [Option<Box<u32>>; 4] = Default::default(); 

    println!("{:?}", myarray);

    myarray[0] = Some(Box::new(1));
    println!("{:?}", myarray);

    let rv = &mut myarray[1];
    *rv = Some(Box::new(2));
    println!("{:?}", myarray);

    let mut rv = &mut myarray[2];
    println!("{:?}", rv);
    rv = &mut myarray[3];
    *rv = Some(Box::new(4));
    rv = &mut myarray[0];
    *rv = None;
    println!("{:?}", myarray);

}

[5. 정리]

정리하면,

  • let mut  A  = &anydata 는 A 라는 변수의 값만 변경할 수 있게 해준다.
    • 포인터의 주소를 변경할 수 있다. (== 참조하려는 대상을 변경 할 수 있다.)
    • 하지만, 포인터가 가리키는 대상에 설정된 값을 변경 할 수는 없다.
  •  let A = &mut anydata 는 A 가 가리키는 대상의 값만 변경 할 수 있게 해준다.
    • 포인터의 주소를 변경 할 수는 없지만, (== 참조하려는 대상은 변경 할 수 없다.)
    • 그러나, 포인터가 가리키는 대상에 설정된 값을 변경 할 수는 있다.
  • let mut A = &mut anydata
    • 둘 다 된다.

[6. 예제

'Rust > 기타 팁' 카테고리의 다른 글

encoding, decoding 관련 crate  (0) 2023.12.26
std::process::Command 관련  (0) 2023.12.26
ssh2 관련  (0) 2023.12.19
Rust. 프로젝트 구조  (0) 2023.12.11
Rust. 알고리즘 문제 풀이 기본 코드 구조  (0) 2023.11.07