Skip to content

str::get_unchecked

str methods · Strings

Level: reference · for working programmers

One line: get with the bounds and boundary checks removed — unsafe, and undefined behaviour if the range is wrong.

pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output

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.

"hé"
[0, 1, 3, 4, 5]
"h"
"é"
"l"
"l"
None
boundary at 2? false

See also

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