str::get_unchecked¶
Level: reference · for working programmers
One line: get with the bounds and boundary checks removed — unsafe, and undefined behaviour if the range is wrong.
Stable since 1.20.0. unsafe — the caller carries the invariant described below.
The safety contract has two clauses, and both must hold:
- the range is within
0..=len() - both endpoints are character boundaries
Violating either is undefined behaviour, not a panic and not mojibake. Producing a &str over invalid UTF-8 breaks the invariant every other method relies on, so the misbehaviour can surface far from the call.
The checks it removes are cheap — a comparison and a byte test — so this only pays inside a measured hot loop where the offsets provably came from char_indices or a previous find. Reach for get or plain indexing first, and let the profiler ask for this.
Example¶
str_get_unchecked.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let s = "héllo";
// Sound: 0 and 3 are boundaries, both within the string.
let head = unsafe { s.get_unchecked(0..3) };
println!("{head:?}");
// The offsets that make it sound come from char_indices.
let bounds: Vec<usize> = s.char_indices().map(|(i, _)| i).collect();
println!("{bounds:?}");
for w in bounds.windows(2) {
println!("{:?}", unsafe { s.get_unchecked(w[0]..w[1]) });
}
// The safe version rejects exactly what the unsafe one would corrupt.
println!("{:?}", s.get(0..2));
println!("boundary at 2? {}", s.is_char_boundary(2));
}
Verified output of str_get_unchecked.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
str::get— the checked versionstr::get_unchecked_mut— the mutable counterpartstr::char_indices— where sound offsets come fromstr::is_char_boundary— the check being skipped
str::get_unchecked in the standard library ↗
Po polsku¶
Kontrakt bezpieczeństwa ma dwa warunki i oba muszą zachodzić naraz: zakres mieści się w 0..=len(), a oba jego końce leżą na granicach znaków. Dla polskiego tekstu te warunki nie są tak samo trudne — pierwszy sprawdza się w głowie, przy drugim żadne przesunięcie wzięte „z sufitu” granicą raczej nie będzie, bo litery z ogonkami i kreskami zajmują po dwa bajty; w przykładzie powyżej granice "héllo" to [0, 1, 3, 4, 5], a is_char_boundary(2) zwraca false. Złamanie któregokolwiek warunku daje niezdefiniowane zachowanie (undefined behaviour), a nie panikę i nie krzaczki: powstaje &str nad niepoprawnym UTF-8, czyli złamany niezmiennik, na którym opierają się wszystkie pozostałe metody — objaw potrafi więc wyjść daleko od miejsca wywołania. Ponieważ usuwane sprawdzenia są tanie (porównanie i test jednego bajtu), kolejność jest tylko jedna: najpierw get albo zwykłe indeksowanie, potem profiler, i dopiero gdy profiler o to poprosi — get_unchecked z przesunięciami pochodzącymi z char_indices albo find.
Szukaj po polsku: niezdefiniowane zachowanie · granica znaku · rust get_unchecked safety · rust unsafe str slicing