Here's my Rust 101 rules for this:
-
"
&strfor parameters;Stringfor return types". This always works, and has no borrowck complications, but is sometimes inefficient. -
the small tweak to add "If you always need to
to_owned/to_stringthe&strparameter, change it to aStringparameter". That's more efficient when your caller happens to already have aString, no less efficient if they don't, and still doesn't require thinking about lifetimes. -
if you're always returning a substring of one of the arguments, add a lifetime generic and return a
&'a str, updating the corresponding parameter from&strto&'a stras well.
That covers the vast majority of cases, but there are of course more complicated scenarios that need something fancier.