println! și print! în Rust

Macro-uri de afișare și formatare Rust 1.0 (variabile în acolade, {nume}: 1.58)

Afișează text pe ieșirea standard: println! adaugă la final un rând nou, print! nu. Acoladele {} sunt înlocuite cu valori.

Sintaxă
println!();                              // doar un rând nou
println!("text");
println!("{} și {}", a, b);              // argumente în ordine
println!("{nume} are {varsta} ani");     // variabile direct în text
print!("fără rând nou");

Ce face println! și print!

println! scrie textul pe ieșirea standard (ecranul) și trece pe rândul următor; print! face la fel, dar fără rând nou. Primul argument trebuie să fie un text literal (șablonul), iar fiecare {} din el este înlocuit cu următorul argument. Șablonul este verificat la compilare: dacă numărul de {} nu corespunde numărului de argumente, programul nu se compilează.

{} folosește trait-ul Display (afișarea „pentru oameni”), iar {:?} folosește Debug (afișarea „pentru programatori”, disponibilă pentru vectori, Option și structurile cu #[derive(Debug)]). Din Rust 1.58 poți scrie variabilele direct în acolade: println!("{nume}"). Pentru acolade propriu-zise scrii {{ și }}.

Între acolade poți adăuga formatare: lățime, aliniere, zecimale ({:.2}), baza de numerație ({:x}, {:b}). Toate opțiunile sunt explicate pe pagina format!, pentru că toate aceste macro-uri folosesc aceeași sintaxă. Ieșirea standard este tamponată pe rând: print! fără rând nou poate să nu apară imediat; apelează std::io::stdout().flush() dacă ai nevoie.

Exemple

Exemplul 1: Argumente, variabile în acolade și Debug

Cele trei moduri de a da valorile: în ordine, cu poziție ({0}) și cu numele variabilei. {:?} afișează vectorul și textul între ghilimele.

fn main() {
    let nume = "Ana";
    let varsta = 17;
    let note = vec![9, 10, 8];
    println!("{} are {} ani", nume, varsta);
    println!("{nume} are {varsta} ani");
    println!("{0}, {0}, {1}!", "Hai", "Rust");
    println!("Note: {note:?}, nume în Debug: {nume:?}");
    println!("Acolade propriu-zise: {{}}");
    println!();
    println!("Media: {:.2}", note.iter().sum::<i32>() as f64 / note.len() as f64);
}

Rezultat

Ana are 17 ani
Ana are 17 ani
Hai, Hai, Rust!
Note: [9, 10, 8], nume în Debug: "Ana"
Acolade propriu-zise: {}

Media: 9.00

Exemplul 2: print! pentru mai multe valori pe același rând

print! nu trece la rând nou, deci valorile din buclă apar pe același rând. println!() de la final încheie rândul.

fn main() {
    print!("Tabla înmulțirii cu 7:");
    for i in 1..=10 {
        print!(" {}", 7 * i);
    }
    println!();

    for rand in 1..=3 {
        for _ in 0..rand {
            print!("*");
        }
        println!();
    }
}

Rezultat

Tabla înmulțirii cu 7: 7 14 21 28 35 42 49 56 63 70
*
**
***

Exemplul 3: Șablonul este verificat la compilare

Șablonul are două {}, dar există un singur argument. Greșeala este găsită la compilare, nu când rulează programul.

fn main() {
    let oras = "Iași";
    println!("{} are {} locuitori", oras);
}

Mesajul compilatorului (programul nu se compilează)

error: 2 positional arguments in format string, but there is 1 argument
 --> main.rs:3:15
  |
3 |     println!("{} are {} locuitori", oras);
  |               ^^     ^^             ----

error: aborting due to 1 previous error

Greșeli frecvente

  • Dai o variabilă ca prim argument: println!(text). Primul argument trebuie să fie un literal; scrie println!("{text}") sau println!("{}", text).
  • Afișezi un vector sau o structură cu {}: `Vec<i32>` doesn't implement `std::fmt::Display`. Folosește {:?} (sau {:#?} pentru afișare pe mai multe rânduri).
  • Scrii în acolade o expresie: println!("{a + b}") sau println!("{elev.nume}"). În acolade sunt permise doar nume simple de variabile; pentru expresii folosește println!("{}", a + b).
  • Folosești print! pentru o întrebare înainte de citirea de la tastatură și textul nu apare. Apelează io::stdout().flush() după print!.

Comenzi înrudite

  • format! (și sintaxa de formatare): Construiește un String nou din șablon și valori, cu aceeași sintaxă ca println!, dar fără să afișeze nimic.
  • eprintln! și eprint!: Ca println! și print!, dar scriu pe ieșirea de eroare (stderr), separată de rezultatul normal al programului.
  • write! și writeln!: Scriu text formatat într-o destinație aleasă: un String, un fișier, stdout sau Formatter-ul din Display. Returnează un Result.
  • dbg!: Afișează rapid, pentru depanare, fișierul, linia, expresia și valoarea ei (în format Debug) pe stderr, apoi returnează valoarea.
  • format_args!: Pregătește un text formatat fără să-l construiască: produce un fmt::Arguments care poate fi scris oriunde, fără alocare.