[1. 개요]
가비지 컬렉터 없이 메모리 안정성을 보장하게 해준다.
메모리는 컴파일 타임에 컴파이럴가 체크할 규칙들로 구성된 소유권 시스템을 통해 관리된다.
소유권 기능들의 그 어떤 것도 런타임 비용이 발생하지 않는다.
러스트 같은 시스템 프로그래밍 언어에서는
값이 스택에 있는지 힙에 있는지 여부가 언어의 동작 방식에 더 큰 영향을 준다.
스택은 데이터에 접근하는 방식때문에 빠르다.
새로운 데이터를 넣어두기 위한 혹은 데이터를 가져올 공간을 검색 할 필요가 없기 때문이며,
스택에 담긴 모든 데이터는 고정된 크기를 갖고 있다.
컴파일 타임에 크기가 결정되지 않거나, 변경될 수 있는 데이터는 힙에 저장된다.
힙 할당은 스택보다 복잡하여 스택보다 느리다.
따라서 코드의 어느 부분이 힙의 어떤 데이터를 사용하는지 추적하는 것,
힙 의 중복 된 데이터의 양을 최소화 하는 것,
힙 내에 사용하지 않는 데이터를 제거하여 공간이 모자라지 않게 하는 것은
모두 소유권과 관계된 문제들이다.
(힙 영역 데이터에 대한 소유권?)
[2. 소유권 규칙]
1. Rust 의 각각의 값은 해당 값의 Owner 라고 불리우는 변수가 갖는다.
2. 한번에 딱 하나의 Owner 만 존재 할 수 있다.
=> 값은 단 하나의 Owner 만 소유 할 수 있다.
3. Owner 가 scope 밖으로 벗어날 때, 값은 버려진다.
[3. String 타입]
이전에 봐온 데이터 타입들은 스택에 저장되었다가 scope 를 벗어 날 때 스택으로 부터 버려진다.
=> scalar type, tuple, array 는 컴파일 시점에 그 크기를 알 수 있다.
문자열 값(리터럴 문자열) 은 immutable 하다.
또, 모든 문자열이 우리가 프로그래밍하는 시점에서 알 수 없기 때문이다.
그러나 String::from() 을 사용하여, 힙에 문자열을 할당 할 수 있다.
또, push_str() 함수를 이용하여 문자열 변경이 가능하다.
(단, 이 경우 mut 변수 이어야 한다.)
해당 문자열은 scope 를 벗어 났을 시, 메모리 공간이 알아서 반납된다.
변수가 scope 밖으로 벗어나면, Rust 는 drop 이라 부르는 특별한 함수를 호출
이 함수는 drop() 이라는 함수로, String 의 메모리를 반납하는 코드를 작성 할 수 있다.
변수와 데이터간 상호작용 => 이동(move)
case1
let x = 5;
let y = x;
변수 x 에 저장된 값이, 변수 y 에도 복사된다.
이는, 변수의 크기를 컴파일 시간에 알 수 있어, 스택에 저장 할 수 있기 때문이다.
case2
let s1 = String::from("hello");
let s2 = s1;
String::from() 은 힙 영역에 데이터를 저장 한다.
그래서, 힙 영역에 데이터를 복사하기 보다는, 힙 영역 데이터의 소유권을 s2 로 넘긴다.
(두 변수 모두 같은 힙 영역을 가리키면, double free 가 발생 할 수 있다.)
따라서 s1 이 소유권을 s2 로 넘긴 후 에는 s1 을 사용 할 수 없다.
변수와 데이터간 상호작용 => 클론
힙 영역 데이터를 깊이 복사하고자 한다면,
clone() 이라는 공용 메소드를 사용 할 수 있다.
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);
스택에만 있는 데이터: 복사
정수형과 같이 컴파일 타임에 결정되는 크기의 타입들은 스택에 모두 저장되므로,
실제 값의 복사가 빠르게 진행 될 수 있다.
Rust 에서는 스택에 저장할 수 있는 타입에 대해 달 수 있는 Copy trait 이 있다.
그래서, 어떤 타입이 Copy trait 을 갖고 있다면, 대입 과정 후에도 변수를 계속 사용 할 수 있다.
그러나, 이 중 Drop trait 을 구현하는 것이 있다면, Copy trait 을 어노테이션 할 수 없게끔 한다.
Copy 가 가능한 타입은 아래와 같다.
- 모든 정수형 타입들
- bool
- 모든 부동소수점 타입
- 위 타입으로 구성된 튜플, (튜플 구성 에서 String 이 끼어있는 경우 불가)
[4. 소유권과 함수]
함수에게 변수를 넘기는 것 역시 값을 이동하거나 복사하게 된다.
값의 반환 역시 소유권을 이동 시킨다.
[99. 보일러 플레이트 코드]