String::insert¶
Level: reference · for working programmers
One line: Inserts one char at a byte offset, shifting everything after it — O(n), and it panics off a character boundary.
Stable since 1.0.0.
The index is a byte offset, with the same two panics as slicing: out of range, or inside a character. s.insert(0, c) is always legal; s.insert(s.len(), c) is push.
Everything after the offset moves, so inserting at the front of a long string in a loop is quadratic. Building in order and using push_str, or collecting an iterator, is almost always better.
The argument is a char; insert_str takes text.
A very common misuse is treating the index as a character position. On non-ASCII text it is not, and the offset has to come from char_indices.
Example¶
string_insert.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");
s.insert(0, '>');
s.insert(3, '-');
println!("{s:?}");
// At the end, it is push.
let n = s.len();
s.insert(n, '!');
println!("{s:?}");
// Byte offsets, not character positions.
let mut accented = String::from("héllo");
println!("boundary at 2? {}", accented.is_char_boundary(2));
let third = accented.char_indices().nth(2).unwrap().0;
accented.insert(third, '-');
println!("{accented:?}");
// Everything after the offset shifts, so this is O(n).
let mut reversed = String::new();
for c in "abcd".chars() {
reversed.insert(0, c);
}
println!("{reversed:?}");
// The linear way to do the same thing.
println!("{:?}", "abcd".chars().rev().collect::<String>());
}
Verified output of string_insert.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
String::insert_str— inserting text rather than one characterString::push— appending, which is O(1) amortizedString::remove— the inversestr::char_indices— where a safe offset comes from
String::insert in the standard library ↗
Po polsku¶
Indeks jest przesunięciem w bajtach, a nie numerem litery, i polszczyzna demaskuje to od razu: "żółw" ma cztery znaki, ale siedem bajtów, bo każda litera z diakrytykiem zajmuje dwa. Stąd najczęstsze nadużycie tej metody — s.insert(2, '-') w intencji „po drugiej literze” potrafi trafić w środek znaku i program panikuje; na stronie widać to jako boundary at 2? false dla "héllo", a poprawne przesunięcie bierze się z char_indices(). Druga sprawa to koszt: wszystko za miejscem wstawienia przesuwa się, więc insert(0, c) w pętli jest kwadratowe — przykład pokazuje obok tańszy zapis "abcd".chars().rev().collect::<String>(), który daje ten sam wynik "dcba" w jednym przebiegu. Na samym końcu łańcucha znaków insert to zwykły push, a do wstawiania całego tekstu zamiast pojedynczego char służy insert_str.
Szukaj po polsku: przesunięcie w bajtach · polskie znaki diakrytyczne w Ruscie · panika na granicy znaku · rust String::insert · rust char_indices byte offset