목차
- Ownership, Lifetime, Borrow Checker
- 소유권과 원시 타입
Ownership, Lifetime, Borrow Checker
소유권(Ownership)과 수명(Lifetime), 빌림 검사기(Borrow Checker)는 Rust 언어가 다른 언어들과 개념적으로 차이가 많이 나는 부분이다.
이 세 가지 개념은 모두 서로 연관되어 있다.
기본적으로 소유권을 가진 소유자는 하나다.
다만 소유권을 가지지 않았다고 해서 해당 변수에 접근하지 못한다는 것을 의미하진 않는다.
소유권은 빌림 검사기가 수명을 체크하기 위해 함께 사용되는 개념이다.
아래 코드는 컴파일되지 않는다.
#[derive(Debug)]
struct Number {
num: i32
}
fn show_number(num: Number) {
println!("{:?}", num);
}
fn main() {
let number = Number { num: 123 };
show_number(number);
println!("{:?}", number);
}
Number
타입은 i32 타입의 num
필드를 갖고 있고, show_number()
함수는 단순히 Number
타입을 출력해 준다.
위 코드가 에러가 발생하는 원인은 fn main()
함수의 마지막 라인에 있다.
에러가 발생한 이유는 number
가 이동된 후 값을 빌리려고 했기 때문이다.
show_number(number)
함수로number
의 소유권이 이동됬다.println!("{:?}", number);
에서 소유권이 이동된number
를 사용하려고 하기 때문에 에러가 발생한다.
빌림 검사기는 수명을 체크하는데,
show_number()
함수로 number
의 소유권이 이동한 시점에서 main()
함수 블록 내에서는 number
의 수명이 끝났다고 볼 수 있다.
정확히는 show_number()
함수 내로 소유권이 이동했고 이 함수가 끝나는 시점에 Drop 되는 것이다.
소유권과 원시 타입
원시 타입에 대해선 위에서 설명한 논리가 적용되지 않는다.
즉, 아래 코드는 문제없이 실행된다.
fn show_number(num: i32) {
println!("{}", num);
}
fn main() {
let num = 123;
show_number(num);
println!("{}", num);
}
앞서 설명한 내용대로라면, show_number(num)
함수로 num
의 소유권이 이동되고 println!("{}", num);
에서 에러가 발생해야 하지만 정상적으로 실행될 것이다.
이유는 Rust가 원시 타입에 대해 Copy 트레잇을 구현하고 있기 때문이다.
Copy 트레잇을 구현한 타입에서 복사는 소유권이 안쪽 범위로 이동하는 경우 항상 암묵적으로 발생한다.
따라서, show_number(num)
호출 시 내부로 복사된 객체가 넘어가며, main()
에서 num
의 소유권은 아직 유효한 것이다.
'Dev > Language' 카테고리의 다른 글
impl Trait과 Box<dyn Trait> - Rust 프로그래밍 (1) | 2022.12.19 |
---|---|
Cell 타입과 RefCell 타입 - Rust 프로그래밍 (1) | 2022.11.26 |
Rc 타입과 Weak 타입 - Rust 프로그래밍 (4) | 2022.10.29 |
트레잇(Trait)과 트레잇 바운드(Trait Bound) - Rust 프로그래밍 (1) | 2022.08.25 |
반복문과 루프 레이블 - Rust 프로그래밍 (0) | 2022.08.14 |