str::into_string¶
Level: reference · for working programmers
One line: Turns a Box<str> into a String without copying — the same allocation, given back its spare capacity field.
Stable since 1.4.0.
It is defined on Box<str>, not on &str, so it is called as boxed.into_string() and consumes the box. That is the trip back from String::into_boxed_str, and both directions are O(1): the bytes never move.
The pair exists because the two types trade the same memory for different guarantees. String carries a capacity field so it can grow; Box<str> drops it, saving eight bytes per value and giving up growth. In a struct held a million times, that is eight megabytes.
Do not confuse it with ToString::to_string ↗, which copies a &str into a fresh allocation. This one moves.
Example¶
str_into_string.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let s = String::from("hello");
let boxed: Box<str> = s.into_boxed_str();
println!("{boxed:?}");
// And back, without copying.
let back: String = boxed.into_string();
println!("{back:?} capacity {}", back.capacity());
// The size difference that motivates Box<str>.
println!("String {} bytes", std::mem::size_of::<String>());
println!("Box<str> {} bytes", std::mem::size_of::<Box<str>>());
// A String with slack loses it on the way out and comes back tight.
let mut roomy = String::with_capacity(64);
roomy.push_str("small");
println!("before {} / {}", roomy.len(), roomy.capacity());
let tight = roomy.into_boxed_str().into_string();
println!("after {} / {}", tight.len(), tight.capacity());
}
Verified output of str_into_string.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
String::into_boxed_str— the other directionstr::into_boxed_bytes— the same move, dropping the UTF-8 promiseString::shrink_to_fit— whatinto_boxed_strdoes on the way
str::into_string in the standard library ↗
Po polsku¶
To bilet powrotny z Box<str> do String i kosztuje dokładnie zero: bajty zostają tam, gdzie były, a wartość odzyskuje jedynie pole pojemności (capacity). O to pole toczy się tu cała gra — wydruk pokazuje String jako 24 bajty, a Box<str> jako 16, więc rezygnacja z możliwości rozrastania się oszczędza osiem bajtów na każdej wartości; w strukturze trzymanej milion razy to osiem megabajtów. Warto przy okazji zapamiętać konwencję nazw, bo w Ruście jest ona umowna, ale konsekwentna: into_ to przejęcie na własność bez kopiowania, natomiast to_string z cechy (trait) ToString kopiuje tekst do świeżej alokacji — nazwy brzmią podobnie, koszt jest zupełnie inny. Skutek uboczny widać w ostatnich liniach przykładu: łańcuch znaków z zapasem 64 wraca jako 5/5, bo into_boxed_str po drodze przycina alokację do rozmiaru treści.
Szukaj po polsku: przejęcie na własność · pojemność łańcucha znaków · rust Box<str> vs String · rust into_string to_string difference