본문 바로가기
개발/Rust

[Rust] 포인터 타입 => 레퍼런스/박스/원시 포인터

by 77monkey 개발자 2023. 10. 9.
반응형

Rust에서 포인터 타입은 크게 3가지로 나뉩니다. Rust에서 포인터 타입은 C/C++에서처럼 포인터가 null이 되거나 중복 해제 등과 같은 일이 발생하지 않습니다. 그렇기 때문에 사람이기 때문에 하는 실수를 사전에 방지할 수 있습니다. 단, unsafe 블록을 사용하는 순간 안전성은 개발자에게 넘어오게 됩니다. 물론 보통의 경우에는 unsafe를 사용하지 않겠지만 말입니다.

 

레퍼런스(&)

레퍼런스는 C/C++에서의 포인터와 유사합니다. 그렇기 때문에 &var를 쓰고 *var를 함으로써 var이 가지고 있는 값을 접근할 수 있습니다. 이러한 레퍼런스는 2가지로 나뉩니다. 불변 참조(&T)와 가변 참조(&mut T)입니다. 불변 참조는 데이터를 읽을 수는 있지만 수정할 수 없고, 가변 참조는 데이터를 읽고 수정할 수 있습니다. 대신에 불변 참조는 여러 개를 만들 수 있지만, 가변 참조는 하나 밖에 못 만듭니다. 생각해 보면 가변 참조를 여러 개 만들어서 수정을 하게 된다면 값을 예측하기 어려워지고 안전성에도 문제가 생깁니다.

레퍼런스에 대한 코드는 아래와 같이 간단하게 짤 수 있는데, 코드 결과는 var1은 10이 되고, var2는 30이 됩니다. 

fn main() {
    let var1 = 10;
    let mut var2 = 20;
    let ref1 = &var1;
    let ref2 = &mut var2;

    *ref2 = 30;

    println!("var1: {} var2: {}", *ref1, *ref2);

}

 

박스(Box)

Box<T>는 힙 메모리에 데이터를 저장하는 스마트 포인터로, 데이터를 소유합니다. 박스는 Box::new()를 통해서 heap에 데이터를 할당할 수 있습니다. 아래 코드는 그 예시입니다. 

fn main() {
    let box_data = Box::new((77, "monkey"));

    println!("box_data: {:?}", box_data);
}
box_data: (77, "monkey")

 

원시 포인터(raw pointer)

원시 포인터는 C/C++에서 사용하는 포인터를 의미합니다. 위에서 레퍼런스가 C/C++에서 포인터와 유사하다고 하였는데, 여기서 말하는 원시 포인터는 아예 같은 것을 의미합니다. 그렇기 때문에 Rust에서 사용하기에는 안전하지 않습니다. 그래서 unsafe 블록 안에서만 사용할 수 있습니다. 보통 FFI와 같이 Rust와 C/C++ 코드 간의 상호 작용에서 사용됩니다.

원시 포인터는 *mut T, *const T로 2가지로 표현할 수 있습니다. *mut T는 가변 원시 포인터라고 생각하시면 되고, *const T는 불변 원시 포인터라고 생각하시면 됩니다.

fn main() {
    let var1 = 10;
    let mut var2 = 20;
    let p1: *const i32 = &var1;
    let p2: *mut i32 = &mut var2;

    unsafe {
        *p2 = 30;
        println!("val1: {} var2: {}", *p1, *p2);
    }
}
val1: 10 var2: 30

 

마무리

Rust에서 사용되는  포인터 타입인 레퍼런스, 박스, 원시 포인터에 대해서 알아보았습니다. C/C++에서 포인터에 대한 개념을 잘 잡아두셨다면 이번 포스팅을 이해하시는데 큰 도움을 받으셨을 것 같습니다. 제가 C/C++에서 포인터를 아직 포스팅하지 않았는데 포스팅을 하게 된다면 한 번 참고 부탁드립니다. 

반응형

'개발 > Rust' 카테고리의 다른 글

[Rust] 쉐도잉(shadowing)  (0) 2024.04.09
[Rust] 슬라이스 vs 슬라이스 레퍼런스  (0) 2023.10.08
[Rust] 벡터(Vector)  (0) 2023.10.05
[Rust] 배열(array)  (0) 2023.10.02
[Rust] 튜플(tuple)  (0) 2023.09.28