vbezhenar
vbezhenar

Reputation: 12356

What is the idiomatic way to convert a String to &str?

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

Answers (1)

Chris Morgan
Chris Morgan

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

Related Questions