&str vs &String


I'm currently studying Slice - String Slices as Parameters

Given example:

fn main() {
    let my_string = String::from("hello world");

    // first_word works on slices of `String`s
    let word = first_word(&my_string[..]);

    let my_string_literal = "hello world";

    // first_word works on slices of string literals
    let word = first_word(&my_string_literal[..]);

    // Because string literals *are* string slices already,
    // this works too, without the slice syntax!
    let word = first_word(my_string_literal);

My questions is, why is this one still working?
This one is not included in example codes but I tried by myself and it's compiled without any issue:

    let word = first_word(&my_string);

Is "&str" equivalent to "&String"?

It's not, but &String can be coerced to &str automatically.


See more at Deref coercions.

fn main() {
    let size_of_ref_to_string = std::mem::size_of::<&String>();
    let size_of_slice = std::mem::size_of::<&str>();
    println!("the size of &String{}", size_of_ref_to_string); //8 bytes
    println!("the size of &str {}", size_of_slice);//16 bytes

We can answer this question from the perspective of memory size, if you have learned c or cpp, you can regard &String as a pointer, which just stores the beginning address of memory allocated for this String.

A string slice is a reference to part of a String

As for slice, we call it fat pointer. Fat means it has something extra besides address info, which is the length(size of the memory allocated) of the part refered by this slice.

check the link below

fat ptr

1 Like

Thank you all above, your reply makes me understand a bit more about Rust.

I raised a Pull Request for this:

The PR was closed, but my commits are manually added into source code.
Hope this would be helpful.

1 Like

Thanks for your reply, but what makes me confused is "expecting a &str but received a &String", why does compiler let this happen? Deref coercoins should be the correct answer.

I don't know where the "expecting a &str but received a &String" error you mentioned came from, but it can happen if generics are involved. Generally, Rust will only perform deref coercions if the target type is not generic.

I didn't see this error output actually, I just assumed this should be an error but it wasn't.
Now I know that it's a feature of Rust.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.