Stack과 heap에 대한 이해가 필요하다. 일반적으로 (스크립트언어가 아니라면) 컴파일 타임에 size를 알수없는경우 heap에 저장한다고 보면 된다.
특징 1. 모든 변수는 scope를 벗어나면 invalid 된다.
Ownership Rules
1. 러스트의 모든 value는 owner를 가지고 있다.
2. 하나의 owner만 가질 수 있다.
3. scope를 벗어나면, value는 없어진다.
가비지컬렉션을 사용하지 않는 언어에서는 직접 메모리를 할당/해제해주어야 하는데, rust에서는 ownership이라는 것을 이용한다. (이를 통해 안전하고 효율적으로 코드를 짤 수 있다고 한다.)
예시 (string literal의 경우 스택에 저장된다.)
{ // s는 invalid한 상황.
let s = "hello" // s는 valid한 상황.
}
// scope를 벗어났으므로, s는 invalid한 상황.
간단하면서도 명확한 방법인 것 같다.
scope를 벗어날 때, rust에서 drop function을 불러 자원을 해제한다. (C++ 에서는 자원해제시, Resource Acquisition Is Initialization (RAII)를 호출한다.)
특징 2. 변수 A = 변수 B 처럼 일반적인 언어에서 변수 B의 값을 변수 A에 저장하려고 하면, 변수 B는 invalid 된다. (Move function)
let x = 5;
let y = x; // x는 invalid된다.
C/C++에서 포인터같은 느낌이다. 주소값을 넘겨주기 때문에 복사가 아니라 Move이다. 다른 점은 x가 invalid 된다는 점이다.
포인터 같은 느낌인 건 아래의 코드를 보면 그렇다.
let s1 = String::from("hello");
let s2 = s1;
왼쪽 그림과 같이 hello 문자열 자체가 복사되는 것이 아니라 주소값이 복사가 되는 것이다.
그 이후 s1은 invalid가 된다.
복사가 아니라 이동하는 것이다. (Shallow Copy + 이전 값 invalid)
만약 복사하고 싶으면 어떻게 하냐?
let s1 = String::from("hello");
let s2 = s1.clone();
그려면 "hello"문자열이 복사가 된다. (Deep Copy라고 생각하면 된다.)
이 부분은 ownership과 관련이 있다. 함수의 파라미터를 복사를 한다면, 함수가 끝나고 나서도 메인문에서 변수가 valid하지만, 파라미터를 Move한다면 함수가 끝나고 파라미터로 넘겨준 변수는 invalid 되는 것이다.
아래의 예시를 보자.
fn main() {
let s = String::from("hello"); // s comes into scope
takes_ownership(s); // s's value moves into the function...
// ... and so is no longer valid here
let x = 5; // x comes into scope
makes_copy(x); // x would move into the function,
// but i32 is Copy, so it's okay to still
// use x afterward
} // Here, x goes out of scope, then s. But because s's value was moved, nothing
// special happens.
fn takes_ownership(some_string: String) { // some_string comes into scope
println!("{}", some_string);
} // Here, some_string goes out of scope and `drop` is called. The backing
// memory is freed.
fn makes_copy(some_integer: i32) { // some_integer comes into scope
println!("{}", some_integer);
} // Here, some_integer goes out of scope. Nothing special happens.
Rust에서 문자열(heap에 저장)은 Move가 되고, 정수형(Stack에 저장)은 Copy가 된다.
참고자료
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
'프로그래밍 > 프로그래밍언어' 카테고리의 다른 글
[rust] Ownership 3 - Reference (0) | 2022.01.01 |
---|---|
[rust] Ownership 2 (0) | 2021.12.28 |
[rust] note: the msvc targets depend on the msvc linker but `link.exe` was not found (0) | 2021.12.22 |
[rust] 윈도우에서 러스트 시작해보기 (0) | 2021.12.22 |
[4장 고차함수] 4.5 합성 함수 (0) | 2021.12.06 |