String::from_utf8_unchecked¶
Level: reference · for working programmers
One line: Takes a Vec<u8> as a String with no validation — unsafe, and undefined behaviour if the bytes are not valid UTF-8.
Stable since 1.0.0. unsafe — the caller carries the invariant described below.
One clause: the bytes must already be valid UTF-8. The scan that from_utf8 performs is skipped entirely.
Both are O(1) in allocation terms — neither copies — so the only saving is the linear scan, which is fast. The justification therefore has to be that the bytes provably came from text: a round trip through into_bytes, or a buffer your own encoder filled.
A String holding invalid bytes is UB, not mojibake. The damage need not appear at the call site.
Example¶
string_from_utf8_unchecked.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let s = String::from("héllo");
// Sound: these bytes came out of a String a moment ago.
let bytes = s.clone().into_bytes();
let back = unsafe { String::from_utf8_unchecked(bytes) };
println!("{back:?} identical={}", back == s);
// The scan being skipped.
let again = "héllo".as_bytes().to_vec();
println!("{:?}", String::from_utf8(again));
// What the checked version refuses.
println!("{:?}", String::from_utf8(vec![0xff, 0xfe]).is_err());
// Neither version copies: from_utf8 costs a scan, not an allocation.
let big = "x".repeat(1000).into_bytes();
let n = big.len();
let text = String::from_utf8(big).unwrap();
println!("{n} bytes in, {} bytes out", text.len());
}
Verified output of string_from_utf8_unchecked.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
String::from_utf8— the checked versionString::into_bytes— the direction that is always soundstr::from_utf8_unchecked— the borrowing counterpartString::as_mut_vec— the other way to hold aString's bytes unsafely
String::from_utf8_unchecked in the standard library ↗
Po polsku¶
Najważniejsze zdanie tej strony brzmi: String z niepoprawnymi bajtami to undefined behavior, a nie krzaczki na ekranie. To rozróżnienie gubią osoby przychodzące z C albo z Pythona, gdzie najgorszym skutkiem złego kodowania jest brzydki tekst — tutaj kompilator ma prawo zakładać, że każdy String jest poprawnym UTF-8, więc szkoda może wyjść gdziekolwiek dalej, niekoniecznie w miejscu wywołania. Warto też odebrać tej funkcji jej zwykłe usprawiedliwienie: from_utf8 również nie kopiuje — obie wersje przejmują tę samą alokację — więc oszczędza się tu wyłącznie jedno liniowe przejście po bajtach, które jest bardzo szybkie. Sięgaj po unsafe tylko wtedy, gdy da się wykazać, że bajty pochodzą z tekstu: po podróży przez into_bytes() albo z bufora wypełnionego własnym koderem.
Szukaj po polsku: niezdefiniowane zachowanie · unsafe w Ruscie · walidacja UTF-8 · rust String::from_utf8_unchecked · rust undefined behavior invalid utf8