Today
-
Yesterday
-
Total
-
  • Rust에서 `Option<String>`을 `&str`로 변환하기
    Programmer/Programming 2025. 12. 4. 11:19
    더보기

    나름 설명해보려고 애를 썼지만, 내 생각이 맞는다는 보장이 없다. 말이 된다고 생각되면 적었으니, 참고만 하시면 좋겠다.

     

    설명을 위해 Rust 함수를 하나 만들보았다.

    fn print_greeting(name: &str) {
        println!("Hello, {}!", name);
    }

     

    우선, String을 &str로 변환하는 몇가지 방법을 나열해보겠다.

    그러자면, 아래와 같이 String 변수 하나를 만들어보자.

    이후 예제 코드는 name 이라는 변수를 사용하겠다.

    let name = String::from("Raphael");

     

     

    1. 가장 흔한 사용 방법은 아래와 같다.

    print_greeting(&name);

    &name&str 타입으로 변환되는 과정은 아래와 같다.

    &namename.as_ref()( String::as_ref(&name) -> &str )&str

     

     

    2. 또는 다음과 같이 호출하기도 한다.

    print_greeting(name.as_ref());

    여기서는 어떤 변환 과정을 거칠까?

    name.as_ref()( String::as_ref(&name) -> &str ) → &str

     

    3.

    print_greeting(name.deref());

    name.deref() ( String::deref(&name) -> &str )  &str

     

    4.

    print_greeting(&*name);

    &*name&( *name )&( String::deref(&name) -> &str ) → ... → &str (중간 생략)

     

    5. slice를 사용하는 부분이 가장 모호하지만, 누군가 잘 아는 분의 피드백을 기대하면 적어본다.

    print_greeting(&name[..]);

    &name[..]&(name[..])&( String::index(name.as_str(), ..) -> SliceIndex<str> )&str

     

    오류가 나는 몇가지 경우의 변환 과정을 살펴보자.

     

    1. deref()를 생각해서 아래와 같이 사용하는 경우이다.

    print_greeting(*name)

    *namestr

    str 타입은 적절한 타입이 아니다.

     

    2. slice 오류의 경우인데, 안전에 서술한대로 이 부분은 설명이 틀릴 가능성이 높다.

    print_greeting(name[..]);

    name[..]  ( String::index(name.as_str(), ..) -> SliceIndex<str> )  str

     

    이제 Option<String>&str로 사용하는 코드를 소개햐겠다.

     

    그에 앞서 name_opt 라는 Option<String> 타입을 먼저 선언하자.

    let name_opt = Some(String::from("Raphael"));

     

    1. 아래와 같이 as_deref()unwrap_or()를 조합하면 수월하게 Option<String> &str 타입으로 전달할 수 있다.

    print_greeting(name_opt.as_deref().unwrap_or("Guest"));

    변환 과정은 다음과 같다.

    name_opt.deref()( Option::as_deref(&Option<String>) -> Option<&str> )Some(&str)

     

    2. as_ref()unwrap_or()를 사용하도 되지만, 불필요하게 문자 리터럴이 String을 생성하는 점이 별로 마음에 들지 않는다.

    print_greeting(name_opt.as_ref().unwrap_or(&String::from("Guest")));

    name_opt.as_ref()( Option::as_ref(&Option<String>) -> Option<&String> )Some(&String) → ...

     

    3. 만약에 아래와 같이 사용한다면, as_deref()as_ref()중에 어느 것을 사용해도 별로 상관이 없을 듯 하다.

    if let Some(name_inner) = name_opt.as_deref() {
        print_greeting(name_inner);
    }

     

    이상 Deref, AsRef trait와 Option::as_deref() 사용 방법을 String, &str 타입으로 설명해보았다.

    댓글

Designed by Tistory.