brunch

Rust : 참조 & 역참조

#Ref #DeRef

by 유윤식

맨날 아리송하게 기억하는 참조 & 역참조


간단하게 String 을 활용해서 참조 & 역참조를 비교해보자.



fn main() {

let s1 = String::from("hello");

let s2 = s1; // s1의 소유권이 s2로 이동

// println!("{}", s1); // 오류: s1은 이미 이동!


let s3 = String::from("world");

let len = calculate_length(&s3); // s3를 빌려줌

println!("'{}의 길이: {}", s3, len); // s3는 여전히 사용 가능 -> 5


let mut s4 = String::from("hello");

change(&mut s4); // 가변 참조로 빌려줌

println!("s4: {}", s4); / -> hello, world!

}


fn calculate_length(s: &String) -> usize { // 불변 참조

s.len()

}


fn change(s: &mut String) { // 가변 참조

s.push_str(", world"); // 자동 역참조 발생에 따라 * 기호가 필요없다.

}



위 코드에서 change 함수를 파악해보면,

s.push_str 을 호출하면서 가변 참조로 가져온 s 변수는 자동 역참조가 일어난다.

즉, *s 를 이용한 명시적 역참조를 할 필요가 없다.


그렇다면, 어떤 경우에 명시적 역참조를 구현할까?

간단하게 .push_str 함수를 사용하지 않고 내가 직접 s 변수를 조작하려고 한다면

명시적 역참조를 사용해야 한다.



fn change(s: &mut String) { // 가변 참조

// s.push_str(", world"); // 자동 역참조 발생에 따라 * 기호가 필요없다.

*s = String::from("Hello, world");

// 또는

*s += ", world";

}


어떤 차이가 있는지 명확히 보인다.


이게 Vec 을 사용하든 HashMap 을 사용하든 대동소이하게 적용된다.

소유권 개념을 이해하려면 해당 개념도 명확하게 이해하고 있어야 안전하게 다음 스텝으로 넘어갈 수 있다.


혹시 struct 와 trait 을 이용해 impl 을 구현한 객체를 사용할 때에도

해당 함수를 호출함으로서 Rust 는 자동 역참조를 일으킨다.


끝.

keyword
작가의 이전글PyTorch 쓰세요(6).