rust 어떻게 &String -> &str이 되는가?

wangki·2025년 3월 17일
1

Rust

목록 보기
28/54

개요

&String 을 어떻게 &str로 자동으로 변환되는지가 궁금하여 글을 작성한다.

내용

rust 코드를 보다보면 &str을 매개변수로 받는데 String 타입의 참조를 넘겨도 컴파일에러가 발생하지 않는 것을 볼 수 있다. 아래는 예시 코드이다.

fn main() {
    let s = String::from("안녕하세요 wanki 입니다.");
    do_something(&s); // &String을 넘겨준다.
}

fn do_something(s: &str) {
    println!("{}", s);
}

&String -> &str 이 자동으로 변환이 되는건가? 라고 생각했다.

fn print_type<T>(s: T) {
    println!("{}", type_name::<T>());
}

위 함수를 만들어서 매개변수의 타입을 출력하도록 하였다.

    // String type에 &를 붙이면 자동으로 변환이 되는가?
    let string = String::from("wanki");
    let str = &string;
    print_type(str);
    print_type(string);

출력 값

&alloc::string::String
alloc::string::String

즉, &를 붙인다고해서 &String -> &str 자동 변환이 이루어지지 않는다.

그렇다면 어떻게 매개변수로 넘겼을 때는 자동으로 변환이 되는 것일까?

정답은 바로 Deref 때문이다. Deref*를 통해서 연관 타입 Target 값으로 변환해주는 트레이트이다. rust에서는 함수의 매개변수로 값을 넘길 때 타입이 다르다면 Deref를 통해 역참조 강제(Deref coercion)를 시도하는 것이다.
&String으로 넘긴 매개변수는 &(*String) 으로 역참조 강제를 시도한 뒤 타입이 일치하다면 컴파일이 된다.

String은 Deref가 구현이 되어있다. 아래와 같다.

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for String {
    type Target = str;

    #[inline]
    fn deref(&self) -> &str {
        self.as_str()
    }
}

참조 http://doc.rust-lang.org/src/alloc/string.rs.html#2604

정리하자면 매개변수로 넘긴 변수의 타입이 일치하지 않는 경우 역참조 강제를 하게 된다. 이 과정에서 *를 명시적으로 사용하지 않아도 컴파일러가 알아서 처리하게된다.

결론

Deref를 구현한 타입의 경우 매개변수의 타입이 일치하지 않는 경우에 역참조 강제를 통해서 *을 명시적으로 상요하지 않고 컴파일러가 알아서 처리하도록 한다. Deref에 대해 이해도가 올라간 것 같다.

2개의 댓글

comment-user-thumbnail
2025년 3월 17일

Deref를 통해 역참조 강제(Deref coercion)를 시도한다니.. 좋은 정보 감사합니다!

1개의 답글