Archive/Rust

[Rustlings] 4. Move Semantics

 여러 프로그래밍 언어마다 메모리 관리법이 다르다. Java는 가비지 컬렉터를 사용하고 C++은 프로그래머가 언제 메모리를 할당하고 해제하는지 직접 지정한다. Rust는 ownership이라는 본연의 시스템으로 메모리를 관리한다.

Ownership은 각 값의 소유권을 변수에게 지정하는 방식이다. ownership은 다음 세가지 방식으로 메모리를 관리한다.

  • 각 값들은 한 변수에게 소유되며, 이러한 변수를 owner라고 한다.
  • 각 변수들은 둘 이상의 값을 소유할 수 없다.
  • owner가 소멸되면 owner가 소유하던 값도 소멸한다.

 보통 가비지 컬렉터를 지원하는 언어는 가비지 컬렉터가 분석해 더이상 사용하지 않는 메모리를 알아서 반환시킨다. 메모리 할당과 해제를 직접 다루는 경우에는 프로그래머가 언제 할당하고 해제하는지를 직접 지정해줘야한다. Rust는 owner가 소멸하는 시점에 owner가 가지고 있던 값의 메모리를 해제한다.

 ownership은 변수에 값을 넘겨줄 때 다른 언어와는 다른 모습을 보여준다. 보통 한 변수에 저장된 값을 다른 변수로 넘겨줄 때 값을 복사해 다른 변수에 저장하거나 메모리 주소나 레퍼런스를 넘겨준다. Rust는 값을 복사하지 않고 아예 값이 이동하는 방식을 취한다. 이를 move라고 한다. 값을 복사하지 않고 이동을 하면 이전 변수는 더이상 넘겨준 값에 접근할 수 없게 된다.

let s1 = String::from("Hello");
let s2 = s1;

// println!(s1); - error: 더이상 owner가 아니라 가지고 있었던 값에 접근할 수 없음
println1(s2);

 move 방식으로 값이 전달되면 힙에 할당된 값들이 이중 해제되거나 같은 데이터가 중복 저장되는 상황을 피할 수 있다. 하지만 함수에 값을 넘겨줄 때는 문제가 발생한다. 해당 값의 owner가 함수의 매개변수로 넘어가기 때문에 값만 가져와 계산하는 경우에는 다시 소유권을 반환해야하는 상황이 발생한다.

fn main() {
  let mut vec: Vec<i32> = Vec::new();
  vec.push(1);
  vec = printOne(vec);
  println!("{}", vec[0]);
}

fn addOne(vec: Vec<i32>) -> Vec<i32> {
  println!("{}", vec[0]);
  vec
}

 그래서 Rust는 레퍼런스를 지원한다. 매개변수에 레퍼런스를 넘기면 소유권은 넘어가지 않고 해당 값에만 접근할 수 있다. 이렇게 레퍼런스를 넘기는 것을 Borrowing이라고 한다.

fn main() {
  let mut vec: Vec<i32> = Vec::new();
  vec.push(1);
  printOne(&vec);
  println!("{}", vec[0]);
}

fn addOne(vec: &Vec<i32>) {
  println!("{}", vec[0]);
}

 &으로 넘기게 되면 해당 값을 불러올수만 있고 값을 바꿀 수 없다. 넘겨준 레퍼런스로 값을 변경도 하고싶다면 &mut을 붙이면 된다.

fn main() {
  let mut vec: Vec<i32> = Vec::new();
  addOne(vec);
  println!("{}", vec[0]);
}

fn addOne(vec: &mut Vec<i32>){
  vec.push(1);
}

 다만 레퍼런스를 쓸 때 주의해야할 사항이 있다. 가변 변수의 레퍼런스를 빌려올 때 같은 scope 내에서 &은 여러번 빌려올 수 있지만 &mut은 무조건 한번만 빌려올 수 있다. 또한 &&mut을 같이 빌려올 수 없다. 그리고 불변 변수는 &mut을 사용할 수 없다.

'Archive > Rust' 카테고리의 다른 글

[Rustlings] 6. struct  (0) 2021.05.16
[Rustlings] 5. Primitive Types  (0) 2021.05.15
[Rustlings] 3. if  (0) 2021.05.12
[Rustlings] 2. Functions  (0) 2021.05.11
[Rustlings] 1. Variables  (0) 2021.05.11