io::Result în Rust

Prescurtare pentru Result<T, io::Error>, tipul returnat de toate operațiile de intrare/ieșire.

Sintaxă
use std::io;

pub type Result<T> = std::result::Result<T, io::Error>;

Ce face io::Result

io::Result<T> nu este un tip nou, ci un alias: înseamnă exact Result<T, io::Error>. Biblioteca standard îl folosește peste tot în std::io și std::fs, ca să nu repete tipul erorii.

Îl poți folosi și în funcțiile tale care fac doar operații cu fișiere: fn incarca() -> io::Result<String>. Cu el, ? funcționează direct pe orice apel de I/O. Și main poate returna io::Result<()>. Scrie io::Result, nu importa std::io::Result direct, ca să nu-l confunzi cu Result obișnuit.

Parametri

Parametru Descriere
T Tipul valorii la succes.

Ce returnează

Este un alias de tip.

Exemple

Exemplul 1: Funcții care întorc io::Result

use std::fs;
use std::io;

fn salveaza_lista(cale: &str, elemente: &[&str]) -> io::Result<()> {
    fs::write(cale, elemente.join("\n"))
}

fn numara_linii(cale: &str) -> io::Result<usize> {
    Ok(fs::read_to_string(cale)?.lines().count())
}

fn main() -> io::Result<()> {
    salveaza_lista("invitati.txt", &["Ana", "Mihai", "Ioana", "Radu"])?;
    println!("invitați: {}", numara_linii("invitati.txt")?);
    println!("lipsa.txt: {:?}", numara_linii("lipsa.txt").map_err(|e| e.kind()));
    Ok(())
}

Rezultat

invitați: 4
lipsa.txt: Err(NotFound)

Exemplul 2: Același tip, scris în două feluri

Cele două funcții au exact aceeași semnătură; compilatorul le acceptă în aceeași variabilă.

use std::io;

fn varianta_scurta() -> io::Result<u8> {
    Ok(1)
}

fn varianta_lunga() -> Result<u8, io::Error> {
    Ok(2)
}

fn main() {
    let functii: [fn() -> io::Result<u8>; 2] = [varianta_scurta, varianta_lunga];
    for f in functii {
        println!("{:?}", f());
    }
}

Rezultat

Ok(1)
Ok(2)

Greșeli frecvente

  • Scrii use std::io::Result; și apoi Result<T, String> în alt loc: alias-ul are un singur parametru, deci primești eroarea type alias takes 1 generic argument but 2 generic arguments were supplied.
  • Folosești ? pe un ParseIntError într-o funcție cu io::Result: nu există conversie automată. Transformă eroarea cu map_err sau folosește Box<dyn Error>.

Comenzi înrudite

  • io::Error: Eroarea operațiilor de intrare/ieșire; kind() dă categoria (NotFound, PermissionDenied…), iar new() creează una proprie.
  • Result: Tipul pentru operații care pot eșua: Ok(valoare) la succes sau Err(eroare) cu motivul eșecului.
  • Error: Trait-ul comun al tuturor tipurilor de eroare: o eroare se poate afișa (Display, Debug) și poate avea o cauză.