|
|
|
|
|
by tmp538394722
1640 days ago
|
|
Just guessing, but speaking from my own experience, the trouble came when interacting with existing APIs, where you can’t choose what to pass around. Some expect String while others expect &str. Once you understand why, it’s easy to intuit which one should be used where, but it was a day 1 speed bump for me. |
|
Like, if you have fn f(s: &str), you can do:
You can see this in playground here [1] (click "Run")To explain: both String and &str is essentially a pointer plus metadata, but &String is a double pointer (a pointer to a pointer). Rust knows how to convert double pointers to pointers, using the Deref trait. This implicit conversion is applied only in a handful of places, and only if it doesn't lead to any ambiguity (if f received a generic parameter it wouldn't work for example).
If you wanted to convert String to &str explictly, you would need to write &*x, like this (see in the playground here [2]):
That's because if x has type String, *x has type str (because String impls Deref<Target = str> [3]) and &*x has type &str. This means that auto-deref changed your &x into &*x automatically.[0] https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-d...
[1] https://play.rust-lang.org/?version=stable&mode=debug&editio...
[2] https://play.rust-lang.org/?version=stable&mode=debug&editio...*
[3] https://doc.rust-lang.org/alloc/string/struct.String.html#im...