Skip to content

str::from_utf8_unchecked_mut

str methods · Strings

Level: reference · for working programmers

One line: from_utf8_unchecked yielding &mut str — unvalidated and mutable, so the invariant is yours at both ends.

pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str

Stable since 1.87.0. unsafe — the caller carries the invariant described below. Usable in a const context.

Two obligations, not one. The bytes must be valid UTF-8 going in, because nothing checks; and they must still be valid when the borrow ends, because the result lets you write.

The safe operations on a &mut str cannot break the second — they are ASCII-for-ASCII and length-preserving. It is reaching further, through as_bytes_mut, that puts the invariant at risk.

This is the rarest method in the family. from_utf8_mut costs one scan and removes the first obligation entirely.

Example

str_from_utf8_unchecked_mut.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let mut buf = *b"hello";

    // Sound: ASCII going in, and an ASCII-preserving edit.
    let s = unsafe { str::from_utf8_unchecked_mut(&mut buf) };
    s.make_ascii_uppercase();
    println!("{:?}", str::from_utf8(&buf).unwrap());

    // The checked version, which costs one scan and removes the obligation.
    let mut other = *b"hello";
    str::from_utf8_mut(&mut other).unwrap().make_ascii_uppercase();
    println!("{:?}", str::from_utf8(&other).unwrap());

    // Multi-byte text: still sound, because the edit leaves non-ASCII alone.
    let mut wide = *"héllo".as_bytes().first_chunk::<6>().unwrap();
    let w = unsafe { str::from_utf8_unchecked_mut(&mut wide) };
    w.make_ascii_uppercase();
    println!("{:?}", str::from_utf8(&wide).unwrap());
}

Verified output of str_from_utf8_unchecked_mut.rs — regenerated by tools/run_examples.py, never hand-typed.

"HELLO"
"HELLO"
"HéLLO"

See also

str::from_utf8_unchecked_mut in the standard library ↗

Po polsku

To jedyna metoda w tej rodzinie, przy której podpisujesz umowę z obu stron: bajty muszą być poprawnym UTF-8 na wejściu, bo nikt tego nie sprawdza, i muszą nim nadal być w chwili, gdy pożyczenie się kończy, bo wynikiem jest &mut str i wolno przez niego pisać. Drugiego warunku bezpieczne metody &mut str nie złamią — działają ASCII na ASCII i nie zmieniają długości w bajtach; złamać go można dopiero sięgając głębiej, przez as_bytes_mut(). Dlatego jest to zarazem najrzadziej potrzebna metoda z całej czwórki: from_utf8_mut kosztuje jedno liniowe przejście po buforze i zdejmuje z ciebie połowę umowy, więc jeśli nie umiesz wskazać palcem miejsca, w którym te bajty powstały już jako tekst, bierz wersję sprawdzaną.

Szukaj po polsku: niezmiennik typu · referencja mutowalna · niezdefiniowane zachowanie · rust from_utf8_unchecked_mut · rust as_bytes_mut invariant