String::truncate¶
Level: reference · for working programmers
One line: Shortens the string to new_len bytes, dropping everything after — panics if that offset is inside a character.
Stable since 1.0.0.
It does nothing if new_len is already at or beyond the length, so it cannot extend and cannot panic for being too large. The only panic is the boundary one.
That asymmetry is the trap: s.truncate(10) is safe on any ASCII string and on any string shorter than 10 bytes, and panics on "héllo wörld". Truncating to a byte budget wants floor_char_boundary first.
The capacity is untouched — this drops text, not memory.
truncate(0) is clear.
Example¶
string_truncate.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut s = String::from("hello world");
s.truncate(5);
println!("{s:?}");
// Beyond the length is a no-op, not a panic.
s.truncate(100);
println!("{s:?}");
// The one panic: an offset inside a character.
let wide = String::from("héllo wörld");
println!("boundary at 8? {}", wide.is_char_boundary(8));
// Truncating to a byte budget safely.
for budget in [2, 8] {
let mut copy = wide.clone();
copy.truncate(copy.floor_char_boundary(budget));
println!("budget {budget:>2} -> {copy:?} ({} bytes)", copy.len());
}
// Capacity is not released.
let mut roomy = String::with_capacity(32);
roomy.push_str("hello world");
roomy.truncate(5);
println!("len {} capacity {}", roomy.len(), roomy.capacity());
}
Verified output of string_truncate.rs — regenerated by tools/run_examples.py, never hand-typed.
"hello"
"hello"
boundary at 8? true
budget 2 -> "h" (1 bytes)
budget 8 -> "héllo w" (8 bytes)
len 5 capacity 32
See also¶
String::clear— truncate(0)String::split_off— keeping the removed tail instead of dropping itstr::floor_char_boundary— making a byte budget safeString::shrink_to_fit— releasing the memory afterwards
String::truncate in the standard library ↗
Po polsku¶
Ta metoda ukarze polskiego czytelnika szybciej niż angielskiego: truncate liczy bajty, a każda litera z diakrytykiem zajmuje w UTF-8 dwa bajty, więc s.truncate(10) przechodzi bez szwanku na "hello world" i panikuje na "żółta łąka", bo bajt 10 wypada w środku drugiego ł — kod przetestowany na ASCII pada dopiero na prawdziwych danych. Asymetria jest przy tym myląca: zbyt duży new_len nie robi nic (tą metodą nie da się wydłużyć łańcucha znaków), a jedyna panika bierze się z trafienia w środek znaku. Kiedy naprawdę chodzi o budżet bajtów — kolumna w bazie, limit w protokole — trzeba najpierw zejść do najbliższej granicy: copy.truncate(copy.floor_char_boundary(budget)), co przy budżecie 2 daje "h", a nie połówkę é. Pojemność pozostaje nietknięta (len 5 capacity 32) — to metoda kasująca tekst, nie pamięć.
Szukaj po polsku: obcinanie łańcucha znaków · polskie znaki a bajty UTF-8 · rust String truncate char boundary panic · rust floor_char_boundary