A
String
type is a container for astr
that is stored on the heap.
Exactly correct.
str
is simply a reference and will most commonly be seen as &str.
&str
is a reference, yes, but str
is not. str
is the actual text itself, no kind of pointer involved. The reason for all the complications is that str
is intrinsically variable-sized, which makes it hard to work with, but when you do, str
is definitely not a reference.
(An example of where you might use neither String
nor &str
is Arc<str>
, a reference-counted string. If you don't know what that means yet, don't worry about it.)
The heuristic I have in my head is that a String type should only be seen as part of the type that owns it. For example, as part of a struct definition.
When being passed into methods, or returning data from a method, then use an &str type as this will work as a reference to the original ownership.
Generally, you should use &str
in function arguments and returns when you can use &str
, but you can't always. In particular, any function which creates a new string that did not previously exist must return String
rather than &str
, because in order to continue existing past the function returning, the string needs to be owned by the return value.
The way I would suggest looking at it is: use &str
when you know there is an owner of the string already, and they will hold still for you to borrow it as long as you need it. If there is no existing owner, or if the owner has its own business that is incompatible with you borrowing it, then you need to use String
.