Rust 기초부터 마스터까지 — 3화
소유권, 빌림, 슬라이스를 코드로 연결하기
본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.
Rust의 소유권은 메모리를 누가 정리할지 컴파일할 때 결정하는 규칙이다. 값을 이동할지, 읽기만 빌릴지, 변경 가능하게 빌릴지를 함수 타입에 표시한다.
값 이동
fn print_name(name: String) {
println!("{name}");
}
let player_name = String::from("Rose");
print_name(player_name);
// player_name은 여기서 다시 사용할 수 없다.
String은 힙 데이터를 소유하므로 대입이나 값 전달 시 소유권이 이동한다. 원본까지 계속 유효하게 두려면 명시적으로 복제하거나 참조를 빌려야 한다.
불변 참조와 가변 참조
fn print_name(name: &str) {
println!("{name}");
}
fn add_suffix(name: &mut String) {
name.push_str("_01");
}
let mut player_name = String::from("Rose");
print_name(&player_name);
add_suffix(&mut player_name);
&str은 문자열 내용을 읽기 위해 잠시 빌리고, &mut String은 값을 변경하기 위해 빌린다. 같은 범위에서 하나의 가변 참조와 다른 참조를 동시에 사용할 수 없다.
이 제한은 읽는 중 값이 바뀌거나 두 곳에서 동시에 수정되는 상황을 막는다.
슬라이스
fn first_word(text: &str) -> &str {
match text.find(' ') {
Some(index) => &text[..index],
None => text,
}
}
슬라이스는 문자열이나 배열의 연속된 일부를 소유하지 않고 바라보는 참조다. String 전체가 필요하지 않은 함수는 &str을 받으면 문자열 리터럴과 String 슬라이스를 모두 사용할 수 있다.
참조의 수명
컴파일러는 참조가 원본보다 오래 살아남지 않는지 확인한다. 지역 변수의 참조를 함수 밖으로 반환하려 하면 원본이 먼저 사라지므로 컴파일되지 않는다.
소유권 오류를 만났을 때 무조건 clone부터 붙이기보다 값의 실제 소유자가 누구여야 하는지 먼저 결정해야 한다. 빌림은 복사를 피하는 기술이면서 동시에 접근 권한을 타입으로 제한하는 계약이다.