Ownership in Signatures
Parameter and return types state the ownership policy of a function. When you write the skeleton you set the policy. When you review, you check that the generated body matches it.
Parameters
| The function takes | It’s saying |
|---|---|
s: &str | “I only need to read this.” The default for read-only use. |
s: String | “I need to keep this”: storing it, sending it, or consuming it. |
s: impl Into<String> | “I need to keep it, and I will do the conversion so callers don’t have to.” |
s: &mut String | “I will edit this string in place.” Rare, and should be deliberate. |
s: Cow<'_, str> | “I sometimes need to keep it. Don’t copy until necessary.” |
A useful review check: does the parameter type match what the body does
with the data? A function that takes String but only reads it forces
every caller to give up or clone a value for no reason. A function that
takes &str and calls .to_string() on the first line has moved the copy
decision to the wrong place.
Returns
- Returning
StringorVec<T>: the function produces owned data. - Returning
&strborrowed from a parameter: no copy, but the output now lives only as long as the input. This is a real design decision. The Lifetime Smells page covers when it’s the wrong one. - Returning
impl Iterator<Item = ..>: the caller decides whether and when to collect.