Hacker News new | ask | show | jobs
by ninkendo 548 days ago
&str doesn’t mean stack-allocated. It’s just a pointer [0] (and a len) to a section of memory that’s (required to be) legal utf-8.

A &str can point at stack memory or heap memory (usually the latter, since it’s common for them to point to a String, which allocate on the heap), or static memory.

But yeah, String keeps things simple, and when in doubt just use it… but if you want to understand it more, it’s better to think of who “owns” the data.

Take a String when you need to build something that needs to own it, like if you’re building a struct out of them, or store them in a hash map or something. Because maybe a caller already “owns” the string and is trying to hand over ownership, and you can avoid the clone if it’s just passed by move.

If you’re only using the string long enough to read it and do something based on it (but don’t want to own it), take a &str, and a caller can be flexible of how it produces that (a &'static str, a String ref, a substring, etc.)

The example that always works for me as a way to remember is to think of HashMap.

HashMap.get takes a reference for the key (analogous to &str), because it’s only using your reference long enough to compare to its keys and see which one matches.

HashMap.insert takes a value for the key (analogous to String) because it needs to own the key and store it in the table.

HashMap.insert could take a reference, but then it’d have to clone it, which means you’d miss out on the opportunity to more cheaply move the key (which is a simple memcpy) instead of calling clone() (which often does more calls to clone and can be complicated)… and only would support clone able keys.

[0] yeah yeah, a reference, not a pointer, but the point is it “points to” a place in memory, which may be heap, stack, static, anything.