Ce face env! (și option_env!)
env!("NUME") se înlocuiește, la compilare, cu valoarea variabilei de mediu NUME. Dacă variabila nu există, compilarea eșuează. option_env!("NUME") dă în schimb un Option<&'static str>, cu None când variabila lipsește.
Cargo setează la compilare multe variabile utile: CARGO_PKG_NAME, CARGO_PKG_VERSION, CARGO_PKG_AUTHORS, CARGO_PKG_DESCRIPTION (din Cargo.toml) și CARGO_MANIFEST_DIR (directorul proiectului). Așa un program își poate afișa versiunea fără să o scrii de două ori.
Valoarea este „înghețată” în executabil: schimbarea variabilei după compilare nu are efect. Pentru variabile citite când rulează programul (de exemplu HOME sau o configurare) folosește std::env::var("NUME").
Exemple
Exemplul 1: option_env!: variabile care pot lipsi
Exemplul este compilat direct cu rustc, fără Cargo, deci CARGO_PKG_VERSION nu există și option_env! dă None. BUILD_ID nu a fost setată nici ea.
const VERSIUNE: Option<&str> = option_env!("CARGO_PKG_VERSION");
const BUILD: &str = match option_env!("BUILD_ID") {
Some(id) => id,
None => "local",
};
fn main() {
println!("Versiune: {}", VERSIUNE.unwrap_or("necunoscută (compilat fără Cargo)"));
println!("Build: {BUILD}");
}
Rezultat
Versiune: necunoscută (compilat fără Cargo)
Build: local
Exemplul 2: env! într-un proiect Cargo
Cargo setează variabilele din Cargo.toml. Numele, versiunea, descrierea și directorul proiectului sunt incluse în executabil la compilare.
// src/main.rs; în Cargo.toml: name = "catalog", version = "1.2.0",
// description = "Catalog electronic pentru note"
fn main() {
println!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
println!("{}", env!("CARGO_PKG_DESCRIPTION"));
let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
println!("proiect: {}", dir.file_name().unwrap().display());
}
$ cargo run -q
Rezultat în terminal
catalog v1.2.0
Catalog electronic pentru note
proiect: catalog
Exemplul 3: Variabilă lipsă: eroare la compilare
CHEIE_API nu este setată, deci env! oprește compilarea cu mesajul dat ca al doilea argument.
fn main() {
let cheie = env!("CHEIE_API", "setează CHEIE_API înainte de compilare");
println!("{} caractere", cheie.len());
}
Mesajul compilatorului (programul nu se compilează)
error: setează CHEIE_API înainte de compilare
--> main.rs:2:17
|
2 | let cheie = env!("CHEIE_API", "setează CHEIE_API înainte de compilare");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
Greșeli frecvente
- Folosești
env!("HOME")crezând că citește directorul utilizatorului care rulează programul. Citește valoarea de pe calculatorul care a compilat; foloseștestd::env::var. - Pui secrete (parole, chei API) în executabil cu
env!: oricine are executabilul le poate extrage. - Folosești
env!("CARGO_PKG_VERSION")într-un fișier compilat fără Cargo: compilarea eșuează. Foloseșteoption_env!dacă codul trebuie să meargă și fără Cargo.
Comenzi înrudite
include_str!: Citește un fișier text la compilare și îl pune în program ca &’static str. Fișierul nu mai este necesar la rulare.cfg!: Evaluează la compilare o condiție de configurare (sistem de operare, mod debug, feature Cargo) și o transformă în true sau false.concat!: Lipește literali (texte, numere, bool, char) într-un singur &’static str, la compilare, fără niciun cost la rulare.Cargo.toml: Fișierul de configurare al unui proiect Rust (în format TOML): numele și versiunea, ediția, dependențele, funcționalitățile și setările de compilare.