let string_slice: &str = &item[0..2];
however, string_slice is now of type &&str (two &s).
That's not right, the type of item[0..2]
is str
so you have to take a reference to use it since it's unsized,
the type of &item[0..2]
is then the &str
you can work with.
When you directly invoke a method on it like here:
let string_slice: &String = &item[0..2].to_string();
due to auto (de-)referencing the compiler will add an automatic reference to the string slice so it desugars to this:
let string_slice: &String = &( // <- the referen you take explicitly
/*the reference the compiler inserts -> */ (&item[0..2]).to_string()
);
I added an extra pair of parentheses to make the precedence clear. So after this string_slice
which is a bit of a misnomer here is of type &String
.
To get a String
instead you can just remove your manual reference.
let string_slice: String = item[0..2].to_string();
which desugars to
let string_slice: String = (&item[0..2]).to_string();
I've annotated all the types above for ease of understanding, but they're exactly what the compiler would infer for them.
As a tip to get the compiler to tell you what type a variable is if you don't have editor support which can tell you you can always add a type annotation of : ()
and the compiler will error with a message telling you what it expected the type to be:
let string_slice: () = &item[0..2];
will error with something like the following
error[E0308]: mismatched types
--> src/main.rs:2:17
|
| let string_slice: () = &item[..];
| -- ^^^^^^^^^ expected `()`, found `&str`
| |
| expected due to this
For more information about this error, try `rustc --explain E0308`.