String::extend_from_within¶
Level: reference · for working programmers
One line: Appends a copy of one of the string's own ranges to its end — self-append without a temporary.
Stable since 1.87.0.
s.extend_from_within(0..3) copies the first three bytes onto the end. Written the obvious way — s.push_str(&s[0..3]) — the borrow checker refuses it: push_str needs &mut s while the argument still borrows s. The usual workaround is a temporary String, and this method removes it.
The range is byte offsets and panics on the same two conditions as slicing, plus out of range.
s.extend_from_within(..) doubles the string, which is the tidiest way to repeat it once.
Stable since 1.87.
Example¶
string_extend_from_within.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut s = String::from("abc");
s.extend_from_within(0..2);
println!("{s:?}");
// Doubling.
let mut d = String::from("xy");
d.extend_from_within(..);
println!("{d:?}");
// The version the borrow checker refuses, and its usual workaround:
// s.push_str(&s[0..2]); // E0502
let mut w = String::from("abc");
let temp = w[0..2].to_string();
w.push_str(&temp);
println!("{w:?} (via a temporary)");
// Byte offsets, with the usual boundary rule.
let mut accented = String::from("héllo");
println!("boundary at 2? {}", accented.is_char_boundary(2));
accented.extend_from_within(0..3);
println!("{accented:?}");
}
Verified output of string_extend_from_within.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
String::push_str— appending text from elsewherestr::repeat— n copies into a fresh stringString::insert_str— copying to a position other than the endString::reserve— sizing the buffer before a big self-append
String::extend_from_within in the standard library ↗
Po polsku¶
extend_from_within dopisuje na koniec łańcucha znaków kopię jego własnego fragmentu i istnieje dokładnie po to, żeby nie walczyć z borrow checkerem: oczywisty zapis s.push_str(&s[0..3]) się nie skompiluje, bo push_str żąda &mut s, podczas gdy argument wciąż trzyma współdzieloną referencję do s. Starsze polskie poradniki każą w tym miejscu zrobić tymczasowy String (let temp = s[0..2].to_string();) — to działa, ale kosztuje dodatkową alokację, a od wersji 1.87 jest już zbędne. Zakres podaje się w bajtach, nie w znakach, więc na "héllo" zakres 0..3 dokłada "hé" (samo é zajmuje dwa bajty), a trafienie w środek znaku kończy się paniką — ta sama reguła granic co przy zwykłym wycinku. Skrót s.extend_from_within(..) podwaja cały łańcuch i jest najkrótszym sposobem na powtórzenie go raz.
Szukaj po polsku: dopisywanie do łańcucha znaków · granica znaku UTF-8 · rust extend_from_within · rust push_str borrow checker E0502