Reputation: 12356
I've found a number of ways to convert String
to &str
. Which one is correct/idiomatic today?
let string = "hello".to_string();
let string_slice1 = &string[..];
let string_slice2: &str = &string;
let string_slice3 = &*string;
How would I make the second method work without specifying type in variable declaration? Something like &string as &str
(but it doesn't work). I see that &string
has &String
type but when it is implicitly cast to &str
, it will perform implicit conversion. How do I make that conversion explicit?
Upvotes: 31
Views: 36679
Reputation: 90872
There are two important things here that String
implements:
Index<RangeFull, Output = str>
: this makes string[..]
be of type str
, though you need to take a reference to it (either by calling a method, allowing autoref to happen, or explicitly as &string[..]
). This explains the string_slice1
.
Deref<Target = str>
: this makes *string
be of type str
, with the same considerations on unsized types as in indexing. This is why string_slice3
works and in a bit of hidden behaviour why string_slice2
works.
Unlike in C++, &
is not a pure reference operator: it also allows dereferencing to take place first. &string
will therefore normally be of type &String
, but it is possible for it to be of type &str
if necessary also. If, for example, you were to pass it to a method that took a &str
, it would work, or if you try to bind it to a variable of type &str
. This is why the : &str
is necessary for this case.
General consensus is that type ascription is to be avoided where feasible, so the second form is not desirable. Between the first and third, there is no consensus as to which is more desirable yet.
There's also String::as_str
, which some prefer:
let string_slice4 = string.as_str();
Upvotes: 41