『TRPL Ch 4. Understanding Ownership』
- 오너십은 러스트의 메모리 관리 방식이다. C에서는 개발자가 직접 메모리를 할당, 해제한다. JVM에서는 가비지 컬렉터가 메모리를 정리한다.
- 오너십에는 세 가지 규칙이 있다.
- 각 값은 오너(owner)라고 부르는 변수를 갖는다.
- 하나의 값은 한 번에 하나의 변수만을 가질 수 있다.
- 오너가 스코프를 벗어나면 값은 버려진다.
{ // s is not valid here, it’s not yet declared
let s = "hello"; // s is valid from this point forward
// do stuff with s
} // this scope is now over, and s is no longer valid
Copy types and Move types
- 어떤 변수를 다른 변수에 할당할 때 타입에 따라 값이 복사되거나 이동한다.
- Copy type
let x = 5;
let y = x; // y is 5, and x is still valid
x의 값이 복사되어 y에 할당된다. 이것을 '값이 복사되었다’라고 말한다.
- 정수, 불리언 등 스택 메모리만을 사용하는 대부분의 원시 타입.
- Move type
let s1 = String::from("hello");
let s2 = s1; // s2 is "hello", and s1 is nolonger valid
s1이 가리키는 메모리 위치를 s2가 가리키고, s1은 메모리 해제된다. 이것을 '값이 이동했다’라고 말한다.
- 값을 복사하려면
clone 메소드를 사용해야 한다. (let s2 = s1.clone())
- 문자열, 벡터 등 비원시 타입.
Ownership and Functions
- 함수 파라미터로 값을 넘기는 것도 변수에 값을 할당하는 것과 비슷하다.
let s = String::from("hello"); // s comes into scope
do_something(s); // s's value moves into the function...
// ... and so is no longer valid here
let x = 5; // x comes into scope
do_something(x); // x would move into the function,
// but i32 is Copy, so it’s okay to still
// use x afterward
References and Borrowing
- 값을 이동시키지 않고 빌려줄 수 있다.
- 변수의 주소를 참조하는 것이다. 단, 값을 변경할 수는 없다. 이것을 shared borrowing이라고 한다.
fn main() {
let a = [1, 2, 3];
let b = &a;
println!("{:?} {}", a, b[0]); // [1, 2, 3] 1
}
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
- 여기서
s는 s1을 참조한다. 함수의 파라미터로 s1의 주소값만 넘기기 때문에 값이 이동하지 않는다.
- 참조한 데이터를 변경하려면
&mut 키워드가 붙어야 한다. 이것을 mutable borrowing이라고 한다.fn main() {
let mut a = [1, 2, 3];
let b = &mut a;
b[0] = 4;
println!("{:?}", b); // [4, 2, 3]
}
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
- 이렇게 하면
change 함수 내에서 some_string을 변경할 때 caller의 s도 변경된다.
이 문서를 인용한 문서