String::into_boxed_str¶
Level: reference · for working programmers
One line: Consumes the String and returns a Box<str> — shrinks to fit and drops the capacity field, saving eight bytes per value.
Stable since 1.4.0.
String is three words: pointer, length, capacity. Box<str> is two — it cannot grow, so it does not need to remember how much room it has. For a value stored once and read many times, that is 8 bytes saved on a 64-bit machine, and in a collection of a million it is 8 MB.
It shrinks first, so any spare capacity is returned to the allocator; that may reallocate and copy.
The trip back is str::into_string, also O(1) — the same allocation, given a capacity field again.
The trade is growth. Use it for finished text — interned names, parsed configuration, map keys — and keep String for anything still being built.
Example¶
string_into_boxed_str.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut s = String::with_capacity(64);
s.push_str("finished");
println!("String len {} capacity {}", s.len(), s.capacity());
let boxed: Box<str> = s.into_boxed_str();
println!("Box<str> len {}", boxed.len());
// Two words instead of three.
println!("String {} bytes / Box<str> {} bytes",
std::mem::size_of::<String>(), std::mem::size_of::<Box<str>>());
// The spare capacity was returned on the way.
let back = boxed.into_string();
println!("back len {} capacity {}", back.len(), back.capacity());
// Everything a &str can do still works; growing does not.
let names: Vec<Box<str>> = ["ada", "grace"].iter().map(|s| (*s).into()).collect();
println!("{:?}", names.iter().map(|n| n.to_uppercase()).collect::<Vec<String>>());
}
Verified output of string_into_boxed_str.rs — regenerated by tools/run_examples.py, never hand-typed.
String len 8 capacity 64
Box<str> len 8
String 24 bytes / Box<str> 16 bytes
back len 8 capacity 8
["ADA", "GRACE"]
See also¶
str::into_string— the trip backString::shrink_to_fit— what this does on the wayString::into_bytes— dropping the UTF-8 guarantee instead of the capacityString::leak— giving up ownership entirely
String::into_boxed_str in the standard library ↗
Po polsku¶
String zajmuje trzy słowa maszynowe — wskaźnik, długość i pojemność — a Box<str> dwa, bo skoro nie może rosnąć, to nie musi pamiętać, ile ma jeszcze wolnego miejsca. Wyjście przykładu pokazuje to wprost: 24 bajty kontra 16, czyli osiem bajtów na wartość, a przy milionie wartości w kolekcji osiem megabajtów. Konwersja nie jest przy tym darmowa — najpierw wykonuje shrink_to_fit, więc nadmiarowa pojemność wraca do alokatora (capacity 64 → capacity 8), co może oznaczać realokację i przepisanie bajtów; płacisz raz, a oszczędzasz stale. Wymieniasz zatem możliwość wzrostu na miejsce na stercie, więc Box<str> pasuje do tekstu skończonego — nazw, sparsowanej konfiguracji, kluczy w mapie — a wszystko, co jeszcze budujesz, zostaje Stringiem; droga powrotna przez into_string() jest tania.
Szukaj po polsku: Box<str> a String · rozmiar typu w pamięci · oszczędzanie pamięci na stercie · rust into_boxed_str · rust Box<str> vs String memory