fmt::Formatter::debug_struct în Rust

Ajută la scrierea manuală a lui Debug în formatul standard Nume { camp: valoare }, inclusiv forma {:#?}.

Sintaxă
f.debug_struct("Nume")
    .field("camp", &self.camp)
    .finish()

Ce face fmt::Formatter::debug_struct

debug_struct(nume) pornește un constructor de text; adaugi câmpuri cu .field("nume", &valoare) și închizi cu .finish(). Rezultatul arată exact ca la #[derive(Debug)], inclusiv afișarea pe mai multe rânduri cu {:#?}.

Îl folosești când vrei un Debug diferit de cel generat automat: ascunzi o parolă, sari peste un câmp intern, adaugi un câmp calculat. .finish_non_exhaustive() adaugă .. la final, ca semn că nu toate câmpurile sunt afișate. Există și debug_tuple, debug_list și debug_map.

Parametri

Parametru Descriere
name Numele afișat în fața acoladelor.
.field(nume, valoare) Un câmp; valoarea trebuie să implementeze Debug.

Ce returnează

Un DebugStruct; finish() returnează fmt::Result.

Exemple

Exemplul 1: Debug care ascunde parola

use std::fmt;

struct Cont {
    utilizator: String,
    parola: String,
}

impl fmt::Debug for Cont {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Cont")
            .field("utilizator", &self.utilizator)
            .field("parola", &"*".repeat(self.parola.len()))
            .finish()
    }
}

fn main() {
    let c = Cont { utilizator: "ana".into(), parola: "secret".into() };
    println!("{c:?}");
    println!("{c:#?}");
}

Rezultat

Cont { utilizator: "ana", parola: "******" }
Cont {
    utilizator: "ana",
    parola: "******",
}

Exemplul 2: Câmp calculat și finish_non_exhaustive

use std::fmt;

struct Cos {
    produse: Vec<(String, u32)>,
}

impl fmt::Debug for Cos {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let total: u32 = self.produse.iter().map(|(_, p)| p).sum();
        f.debug_struct("Cos")
            .field("nr_produse", &self.produse.len())
            .field("total_lei", &total)
            .finish_non_exhaustive()
    }
}

fn main() {
    let cos = Cos { produse: vec![("pâine".into(), 5), ("lapte".into(), 8)] };
    println!("{cos:?}");
}

Rezultat

Cos { nr_produse: 2, total_lei: 13, .. }

Greșeli frecvente

  • Uiți .finish(): nu compilează, pentru că funcția trebuie să returneze fmt::Result, nu &mut DebugStruct.
  • Scrii manual write!(f, "Cont {{ ... }}"): pierzi forma frumoasă pentru {:#?}. debug_struct o oferă automat.

Comenzi înrudite

  • fmt::Debug: Trait-ul pentru afișarea de depanare cu {:?} și {:#?}; se obține aproape mereu cu #[derive(Debug)].
  • fmt::Formatter: Obiectul primit de fmt() în Display și Debug: destinația textului plus opțiunile din {:…} (lățime, precizie, #).
  • fmt::Display: Trait-ul pentru afișarea către utilizator cu {}; se implementează manual și aduce automat to_string().