Search code examples
rust

How does a reference to a String become a string slice?


I'm trying to understand the concept of strings and string slices.

fn say_hello_slice(slice: &str) {
    println!("Hey {}", slice);
}

fn say_hello_string(string: &String) {
    println!("{:?}", string);
}

fn print_int(int_ref: &i32) {
    println!("{:?}", int_ref);
}

fn main() {
    let slice: &str = "you";
    let s: String = String::from("String");
    say_hello_slice(slice);
    say_hello_slice(&s);

    let number: i32 = 12345;
    print_int(&number);

    say_hello_string(&s);
}

This program gives the below output when I compile and run:

Hey you
Hey String
12345
"String"

I understand that when & is added to the binding it becomes a reference to its binding type. For example, & to number in above program becomes &i32.

I don't understand how it works when I add & to String and it becomes &str.


Solution

  • You have just witnessed the Deref trait. This trait has three uses:

    • Conversion to another type when dereferencing (the * operator)
    • Automatic conversion if necessary (coercion) when borrowing
    • You can call methods of another type directly.

    In your case, because String implements Deref<Target = str> this means that &s can be coerced to a &str.

    More info in the Deref section of String.