Skip to content

String::from_utf8

String methods · Strings

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.

pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>

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.

Ok("hi")
failed at byte 1
recovered [104, 255, 105]
None
"héllo" 6 bytes

See also

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