Условная компиляция на языке Rust |
![]() |
Добавил(а) microsin | ||||||||||||||||||
Рано или поздно по мере освоения возможностей языка Rust встает вопрос: есть ли на нем условная компиляция, наподобие директив препроцессора #if, #ifdef, #elif, #else, #endif языка C? Это очень распространенная проблема для разработчиков, переходящих из C/C++ на Rust. Короткий ответ: нет. На языке Rust нет препроцессора с директивами в стиле #ifdef или #if, работающих на том же уровне, что и на C/C++. Однако Rust обладает мощной и более интегрированной системой для условной компиляции, которая служит той же цели. Это реализовано через атрибуты и cfg-систему (от слова configuration). [Rust-эквивалент препроцессора: #[cfg(...)] Вместо отдельного шага препроцессора, Rust обрабатывает условную компиляцию на уровне языка с помощью атрибутов. Самый важный из них это #[cfg(...)]. Вот как концепция C/C++ выглядит по сравнению с Rust: 1. #ifdef FEATURE / #if defined(FEATURE) на языке C: #ifdef UNIX Аналог на Rust: #[cfg(unix)] { Или для функции: #[cfg(unix)] 2. #ifndef FEATURE (if NOT defined) на языке C: #ifndef WINDOWS Аналог на Rust: #[cfg(not(windows))] { 3. #else на языке C: #ifdef UNIX Аналог на Rust: #[cfg(unix)] { 4. #elif (else if) на языке C: #if defined(UNIX) Аналог на Rust: #[cfg(unix)] { На Rust есть несколько общих предопределенных условий для cfg: • Операционные системы: windows, unix, linux, macos Пользовательские фичи: вы их можете определить самостоятельно (см. далее). [Определение ваших собственных фич (наподобие -D компилятора GCC)] На языке C вы можете компилировать код с -DDEBUG_MODE. На Rust вы определяете пользовательские фичи в своем файле Cargo.toml: [features] Затем, в вашем коде Rust: // Эта функция компилируется только если разрешена фича "advanced_mode": Вы можете также использовать это совместно с другими условиями: #[cfg(all(unix, feature = "special_algorithm"))] Чтобы запустить сборку с разрешенной фичей, используйте Cargo с опцией --features, например: $ cargo build --features "advanced_mode"
.. или для релиза: $ cargo build --release --features "advanced_mode"
[Макрос cfg! для условной проверки runtime] Атрибут #[cfg] удаляет код во время компиляции. Если вам нужно проверять наличие фичи runtime (код скомпилирован, но есть ветвления кода), то используйте макрос cfg!. Он возвратит bool. if cfg!(target_os = "macos") { [Общие выводы: ключевые отличия от C]
Система условной компиляции Rust считается в основном более безопасной и надежной, поскольку она понимает структуру кода, защищая от общих ошибок препроцессора наподобие несоответствующих директив #endif. |