String::from_utf8 în Rust

String Rust 1.0

Creează un String din octeți: from_utf8 verifică UTF-8 și dă eroare; from_utf8_lossy înlocuiește octeții greșiți cu �.

Sintaxă
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>
pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str>

Ce face String::from_utf8

Un String trebuie să conțină mereu UTF-8 valid. from_utf8 primește un Vec<u8>, verifică octeții și returnează Ok(String) sau Err cu poziția primului octet greșit. Nu copiază: folosește direct vectorul primit.

from_utf8_lossy nu eșuează niciodată: înlocuiește fiecare secvență invalidă cu caracterul � (U+FFFD). Primește un împrumut &[u8] și returnează un Cow<str>: dacă octeții erau corecți, este doar o privire spre ei (fără copiere); dacă a trebuit să înlocuiască ceva, este un String nou. Este util pentru ieșirea unor programe externe sau fișiere în codificare necunoscută.

Textele vechi românești salvate în Windows-1250 sau ISO-8859-2 (unde ș este un singur octet) nu sunt UTF-8 valid; from_utf8 le respinge.

Parametri

Parametru Descriere
vec Octeții, ca vector (from_utf8 îl consumă).
v Octeții, ca împrumut (from_utf8_lossy).

Ce returnează

from_utf8: Result<String, FromUtf8Error>. from_utf8_lossy: Cow<str>, care se folosește ca un &str și se transformă în String cu into_owned().

Exemple

Exemplul 1: Octeți corecți și octeți greșiți

Octetul 0xBA este litera ș în ISO-8859-2, dar în UTF-8 este invalid.

fn main() {
    let bun = vec![73, 97, 200, 153, 105];          // "Iași" în UTF-8
    let rau = vec![73, 97, 0xBA, 105];              // "Iași" în ISO-8859-2

    match String::from_utf8(bun) {
        Ok(s) => println!("ok: {s}"),
        Err(e) => println!("eroare: {e}"),
    }
    match String::from_utf8(rau) {
        Ok(s) => println!("ok: {s}"),
        Err(e) => println!("eroare: {e}"),
    }
}

Rezultat

ok: Iași
eroare: invalid utf-8 sequence of 1 bytes from index 2

Exemplul 2: from_utf8_lossy nu eșuează

use std::borrow::Cow;

fn main() {
    let rau = [73, 97, 0xBA, 105];
    let text = String::from_utf8_lossy(&rau);
    println!("{text}");

    let bun = "Galați".as_bytes();
    let text2 = String::from_utf8_lossy(bun);
    let fara_copie = matches!(text2, Cow::Borrowed(_));
    println!("{text2} (fără copiere: {fara_copie})");
}

Rezultat

Ia�i
Galați (fără copiere: true)

Greșeli frecvente

  • Folosești from_utf8(...).unwrap() pe date venite din afară (fișiere, rețea). La primul octet greșit programul se oprește cu panică. Tratează Err sau folosește from_utf8_lossy.
  • Dai lui from_utf8 un &[u8]. Cere un Vec<u8>; pentru un împrumut există std::str::from_utf8, care returnează Result<&str, _>.

Comenzi înrudite

  • String::into_bytes: Transformă String-ul în Vec<u8> cu octeții lui UTF-8, fără copiere; String-ul este consumat.
  • str::bytes: Accesul la octeții UTF-8 ai textului: bytes() ca iterator de u8, as_bytes() ca felie &[u8].
  • Cow: „Clone on write”: ține fie un împrumut, fie o valoare deținută; copiază datele doar dacă trebuie modificate.
  • String: Textul care îți aparține și se poate modifica: UTF-8, pe heap, crește singur. Diferența față de &str.