use în Rust

Aduce în domeniu un nume dintr-un modul sau crate (std::collections::BTreeMap), ca să-l poți folosi fără calea completă.

Sintaxă
use std::collections::BTreeMap;
use std::io::{self, Write};          // mai multe nume deodată
use std::fmt::Result as FmtResult;   // redenumire
use std::collections::*;             // tot (de evitat)
pub use interior::Functie;            // re-export

Ce face use

use creează o scurtătură: după use std::collections::BTreeMap;, scrii doar BTreeMap. Fără el, ai scrie de fiecare dată std::collections::BTreeMap. Câteva nume foarte des folosite (Vec, String, Option, Some, Ok, Box, trait-urile Clone, Iterator) sunt deja în preludiu și nu trebuie importate.

Acoladele importă mai multe nume din același loc: use std::io::{self, BufRead, Write}; (self importă chiar modulul io). as redenumește un import, util când două nume se ciocnesc (std::fmt::Result și std::io::Result). * importă tot din modul, dar face codul greu de urmărit.

Pentru a apela metodele unui trait, trait-ul trebuie să fie în domeniu: write! pe un String cere use std::fmt::Write;. Un import nefolosit produce un avertisment (cu -D warnings, eroare). pub use re-exportă un nume, ca utilizatorii bibliotecii tale să-l găsească într-un loc mai simplu.

Exemple

Exemplul 1: Importuri simple, grupate și redenumite

BTreeMap și BTreeSet vin din același modul, deci sunt importate împreună. Write (trait-ul) este necesar pentru writeln! pe stdout, iar io este importat cu self. Ordering primește alt nume cu as.

use std::cmp::Ordering as Ordine;
use std::collections::{BTreeMap, BTreeSet};
use std::io::{self, Write};

fn main() {
    let mut populatie = BTreeMap::new();
    populatie.insert("Iași", 271_692);
    populatie.insert("Cluj-Napoca", 286_598);
    let judete: BTreeSet<&str> = ["IS", "CJ", "IS"].into_iter().collect();

    let mut iesire = io::stdout();
    for (oras, nr) in &populatie {
        writeln!(iesire, "{oras}: {nr}").unwrap();
    }
    writeln!(iesire, "Județe distincte: {judete:?}").unwrap();

    let rezultat = populatie["Iași"].cmp(&populatie["Cluj-Napoca"]);
    if rezultat == Ordine::Less {
        println!("Iași are mai puțini locuitori decât Cluj-Napoca");
    }
}

Rezultat

Cluj-Napoca: 286598
Iași: 271692
Județe distincte: {"CJ", "IS"}
Iași are mai puțini locuitori decât Cluj-Napoca

Exemplul 2: use cu propriile module și pub use

pub use re-exportă formatare::lei direct din unelte, deci main îl importă ca unelte::lei. use unelte::conversii::* aduce toate funcțiile publice din conversii.

mod unelte {
    pub use self::formatare::lei;

    pub mod formatare {
        pub fn lei(suma: f64) -> String {
            format!("{suma:.2} lei")
        }
    }

    pub mod conversii {
        pub fn din_euro(euro: f64) -> f64 {
            euro * 4.97
        }

        pub fn din_dolari(dolari: f64) -> f64 {
            dolari * 4.56
        }
    }
}

use unelte::conversii::*;
use unelte::lei;

fn main() {
    println!("{}", lei(din_euro(20.0)));
    println!("{}", lei(din_dolari(15.0)));
}

Rezultat

99.40 lei
68.40 lei

Greșeli frecvente

  • Apelezi o metodă dintr-un trait neimportat (de exemplu write_all sau read_line) și primești no method named .... Mesajul compilatorului îți spune ce use lipsește.
  • Lași importuri nefolosite după o refactorizare: avertismentul unused import oprește build-ul când avertismentele sunt tratate ca erori.
  • Imporți două nume identice (use std::fmt::Result; use std::io::Result;): eroarea E0252. Redenumește unul cu as sau importă modulul (use std::fmt; și scrie fmt::Result).

Comenzi înrudite

  • module și vizibilitate (mod, pub, crate, super): mod împarte codul în module; tot ce este într-un modul este privat implicit, iar pub îl face vizibil. crate și super încep căile.
  • trait: Definește un set de metode pe care un tip promite să le aibă. Seamănă cu interfețele din alte limbaje și stă la baza generics.
  • as (conversii numerice): Convertește explicit o valoare numerică (sau char, bool) în alt tip primitiv. Conversia nu dă niciodată eroare, dar poate pierde informație.
  • 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.