Ce face cfg!
cfg!(conditie) se înlocuiește la compilare cu true sau false, după configurarea compilării. Condițiile sunt aceleași ca la atributul #[cfg(...)]: target_os = "windows", unix, windows, target_arch = "aarch64", debug_assertions, test, feature = "nume", combinate cu any, all și not.
Diferența față de #[cfg]: cu cfg!, ambele ramuri ale unui if sunt compilate, deci trebuie să fie cod valid pe orice sistem; doar valoarea condiției diferă. Cu #[cfg], codul care nu corespunde este eliminat înainte de compilare, deci poate folosi funcții care există doar pe un anumit sistem.
Folosește cfg! pentru diferențe mici de comportament (un mesaj, o valoare implicită) și #[cfg] când codul nu s-ar compila pe celelalte sisteme.
Ce returnează
true sau false, constantă la compilare.
Exemple
Exemplul 1: Informații despre compilare
Exemplul a fost compilat și rulat pe un Mac cu procesor Apple (macOS, aarch64), fără optimizări, deci debug_assertions este activ. Pe Linux sau Windows, rândurile ar arăta altfel.
fn main() {
let sistem = if cfg!(target_os = "windows") {
"Windows"
} else if cfg!(target_os = "macos") {
"macOS"
} else if cfg!(target_os = "linux") {
"Linux"
} else {
"alt sistem"
};
println!("Sistem: {sistem}, Unix: {}", cfg!(unix));
println!("64 de biți: {}", cfg!(target_pointer_width = "64"));
println!("ARM pe 64 de biți: {}", cfg!(target_arch = "aarch64"));
println!("mod debug: {}", cfg!(debug_assertions));
}
Rezultat
Sistem: macOS, Unix: true
64 de biți: true
ARM pe 64 de biți: true
mod debug: true
Exemplul 2: Valoare implicită diferită pe sisteme diferite
Ambele ramuri sunt compilate pe orice sistem, pentru că sunt simple texte. Pe macOS și Linux se alege calea de tip Unix.
fn director_config() -> &'static str {
if cfg!(windows) {
r"C:\ProgramData\catalog"
} else {
"/etc/catalog"
}
}
fn main() {
println!("Configurarea se caută în {}", director_config());
if cfg!(debug_assertions) {
println!("(versiune de dezvoltare: verificări suplimentare active)");
}
}
Rezultat
Configurarea se caută în /etc/catalog
(versiune de dezvoltare: verificări suplimentare active)
Greșeli frecvente
- Folosești
if cfg!(windows) { functie_doar_windows() }: pe Linux ramura este tot compilată, iar funcția nu există, deci build-ul eșuează. Folosește#[cfg(windows)]pe funcție sau pe bloc. - Verifici
cfg!(feature = "x")pentru o funcționalitate nedeclarată în[features]: compilatorul avertizeazăunexpected `cfg` condition value.
Comenzi înrudite
atribute (#[derive], #[cfg], #[allow]): Informații pentru compilator scrise cu #[…] deasupra unui element: generează cod (derive), aleg codul compilat (cfg) sau schimbă avertismentele.env! (și option_env!): Citește o variabilă de mediu la compilare și o pune în program ca &’static str. Pentru valori la rulare se folosește std::env::var.assert! și debug_assert!: Verifică o condiție la rulare și dă panică dacă este falsă. debug_assert! face verificarea doar în modul debug, nu și în release.line!, file! și column!: Dau poziția din codul sursă unde sunt scrise: numărul liniei, coloana și numele fișierului. Utile în mesaje de jurnal și erori.