본문 바로가기

Rust

참조자와 빌림

[1. 개요]

값의 소유권을 넘기는 대신 개체애 대한 참조자를 사용하는 방법

변수 타입 앞에 & 을 표기한다.

let s1 = String::from("hello");

let len = calculate_length(&s1); // s1 의 값을 참조하지만, 소유하지는 않는다.

 

주의 할 점은 참조자의 실 소유권이 사용 중 소멸되지 않아야 한다.

 

함수의 파라미터로 참조자를 만든 것을 빌림 이라고 한다.

 

참조자 역시 기본적으로 불변한다. 

 

 

[2. 가변 참조자]

fn main() {
    let mut s = String::from("hello");

    change(&mut s);
}

fn change(some_string: &mut String) { // &String -> &mut String
    some_string.push_str(", world");
}

 

가변 참조자는 한가지 제한 사항이 있다.

 

특정 스코프 내 특정 데이터에 대한 가변참조자는 딱 하나만 존재 할 수 있다.

=> 이를 통해 컴파일 타임에 Data race 를 방지 할 수 있게 한다.

 

Data race 는 아래와 같은 상황에서 발생한다.

  1. 두 개 이상의 포인터가 동시에 같은 데이터에 접근
  2. 이 중 적어도 하나의 포인터가 데이터를 write 한다.
  3. 데이터에 접근하는데 동기화를 하는 어떠한 메커니즘이 없다.

동시에 여러 가변 참조자는 만들 수 없기에

스코프 내 새로운 스코프를 열면, 여러 번 가변 참조자를 만들 수 있다.

 

가변 참조자와 불변 참조자를 혼용 할 수 없다.

=> 불변 참조자 사용 중 값이 바귀는 것을 허용하지 않는다.

이는 컴파일 시점에 확인 할 수 있다.

 

 

[3. Dangling 참조자]

해제된 메모리를 가리키는 포인터

fn main() {
    let reference_to_nothing = dangle();
}

fn dangle() -> &String {
    let s = String::from("hello"); // 힙에 변수 할당

    &s // 참조자 반환,
}
// 변수 s 는 소멸

위 코드는 컴파일 되지 않는다.

 

 

[4. 정리]

어떤 변수에 대한 참조자는 아래와 같은 경우에만 사용 할 수 있다.

  1. 하나의 가변 참조자
  2. 여러개의 불변 참조자들

또한, 참조자는 항상 유효해야 한다.

(참조자가 가리키는 메모리는 항상 유효해야 한다.)

'Rust' 카테고리의 다른 글

Rust 구조체  (0) 2022.08.20
슬라이스  (0) 2022.08.18
소유권  (0) 2022.08.17
함수와 제어문  (0) 2022.08.17
Rust 변수  (0) 2022.08.08