String::from_utf8¶
Level: reference · for working programmers
One line: Validates a Vec<u8> and takes ownership of it as a String — no copy, and the failed Vec is handed back in the error.
Stable since 1.0.0.
The bytes are scanned once; if they are valid the same allocation becomes the String. That is the difference from str::from_utf8, which borrows: this one moves.
The error type is FromUtf8Error, and it is unusually considerate — into_bytes() gives your Vec back, so a rejection does not cost you the data. utf8_error() gives the same Utf8Error detail as the borrowing version: where the scan failed, and whether the input was invalid or merely truncated.
This is what you call after reading a file or a socket into a Vec<u8> when the bytes are supposed to be text and a violation is an error worth reporting. When it is not worth reporting, from_utf8_lossy substitutes replacement characters instead.
Example¶
string_from_utf8.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let good = vec![104, 105];
println!("{:?}", String::from_utf8(good));
// The Vec comes back on failure -- the data is not lost.
let bad = vec![104, 0xff, 105];
match String::from_utf8(bad) {
Ok(s) => println!("{s:?}"),
Err(e) => {
println!("failed at byte {}", e.utf8_error().valid_up_to());
println!("recovered {:?}", e.into_bytes());
}
}
// Truncated rather than invalid: error_len is None.
let cut = "é".as_bytes()[..1].to_vec();
println!("{:?}", String::from_utf8(cut).unwrap_err().utf8_error().error_len());
// It moves rather than copying: the Vec is consumed.
let owned = "héllo".as_bytes().to_vec();
let text = String::from_utf8(owned).unwrap();
println!("{text:?} {} bytes", text.len());
}
Verified output of string_from_utf8.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
String::from_utf8_lossy— substituting instead of failingString::from_utf8_unchecked— skipping the scan, unsafelyString::into_bytes— the reverse movestr::from_utf8— the borrowing version
String::from_utf8 in the standard library ↗
Po polsku¶
Ta funkcja przejmuje własność wektora bajtów i przy powodzeniu oddaje tę samą alokację jako String, bez kopiowania — na tym polega różnica wobec str::from_utf8, które tylko pożycza. Z przejęcia własności bierze się drobny problem projektowy, rozwiązany tu na tyle ładnie, że warto go podpatrzeć do własnego kodu: skoro Vec został przeniesiony do środka, samo Err oznaczałoby utratę danych, więc FromUtf8Error niesie je z powrotem i into_bytes() oddaje wektor w całości (w przykładzie: recovered [104, 255, 105]). Do diagnostyki służy utf8_error() — valid_up_to() mówi, do którego bajtu było dobrze, a error_len() odróżnia dane błędne od uciętych: None znaczy „skończyło się w połowie znaku”, co przy czytaniu z gniazda zwykle oznacza „doczytaj resztę”, a nie „odrzuć porcję”. Gdy naruszenie nie jest warte zgłaszania, jest from_utf8_lossy.
Szukaj po polsku: walidacja UTF-8 · przejęcie własności wektora · obsługa błędów · rust String::from_utf8 · rust FromUtf8Error into_bytes