1. 1. Introduction
  2. 2. Введение
  3. 3. C чего начать
  4. 4. Изучение Rust
    1. 4.1. Угадайка
    2. 4.2. Обедающие философы
    3. 4.3. Вызов кода на Rust из других языков
  5. 5. Синтаксис и семантика
    1. 5.1. Связывание имён
    2. 5.2. Функции
    3. 5.3. Простые типы
    4. 5.4. Комментарии
    5. 5.5. Конструкция `if`
    6. 5.6. Циклы
    7. 5.7. Владение
    8. 5.8. Ссылки и заимствование
    9. 5.9. Время жизни
    10. 5.10. Изменяемость
    11. 5.11. Структуры
    12. 5.12. Перечисления
    13. 5.13. Конструкция `match`
    14. 5.14. Шаблоны сопоставления `match`
    15. 5.15. Синтаксис методов
    16. 5.16. Вектора
    17. 5.17. Строки
    18. 5.18. Обобщённое программирование
    19. 5.19. Типажи
    20. 5.20. Типаж `Drop`
    21. 5.21. Конструкция `if let`
    22. 5.22. Типажи-объекты
    23. 5.23. Замыкания
    24. 5.24. Универсальный синтаксис вызова функций
    25. 5.25. Контейнеры и модули
    26. 5.26. `const` и `static`
    27. 5.27. Атрибуты
    28. 5.28. Псевдонимы типов
    29. 5.29. Приведение типов
    30. 5.30. Ассоциированные типы
    31. 5.31. Безразмерные типы
    32. 5.32. Перегрузка операций
    33. 5.33. Преобразования при разыменовании
    34. 5.34. Макросы
    35. 5.35. Сырые указатели
    36. 5.36. Небезопасный код
  6. 6. Эффективное использование Rust
    1. 6.1. Стек и куча
    2. 6.2. Тестирование
    3. 6.3. Условная компиляция
    4. 6.4. Документация
    5. 6.5. Итераторы
    6. 6.6. Многозадачность
    7. 6.7. Обработка ошибок
    8. 6.8. Выбор гарантий
    9. 6.9. Интерфейс внешних функций
    10. 6.10. Типажи `Borrow` и `AsRef`
    11. 6.11. Каналы сборок
    12. 6.12. Using Rust without the standard library
  7. 7. Нестабильные возможности Rust
    1. 7.1. Плагины к компилятору
    2. 7.2. Встроенный ассемблерный код
    3. 7.3. Без stdlib
    4. 7.4. Внутренние средства
    5. 7.5. Элементы языка
    6. 7.6. Продвинутое руководство по компоновке
    7. 7.7. Тесты производительности
    8. 7.8. Синтаксис упаковки и шаблоны `match`
    9. 7.9. Шаблоны `match` для срезов
    10. 7.10. Ассоциированные константы
    11. 7.11. Пользовательские менеджеры памяти
  8. 8. Глоссарий
  9. 9. Syntax Index
  10. 10. Библиография

Условная компиляция

В Rust есть специальный атрибут, #[cfg], который позволяет компилировать код в зависимости от флагов, переданных компилятору. Он имеет две формы:

#[cfg(foo)]

#[cfg(bar = "baz")]Run

Над атрибутами конфигурации определены логические операции:

#[cfg(any(unix, windows))]

#[cfg(all(unix, target_pointer_width = "32"))]

#[cfg(not(foo))]Run

Они могут быть как угодно вложены:

#[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]Run

Что же касается того, как включить или отключить эти флаги: если вы используете Cargo, то они устанавливаются в разделе [features] вашего Cargo.toml:

[features]
# по умолчанию, никаких дополнительных возможностей
default = []

# возможность «secure-password» зависит от пакета bcrypt
secure-password = ["bcrypt"]

Если вы определите такие возможности, Cargo передаст флаг в rustc:

--cfg feature="${feature_name}"

Совокупность этих флагов конфигурации (cfg) будет определять, какие из них будут активны, и, следовательно, какой код будет скомпилирован. Давайте рассмотрим такой код:

#[cfg(feature = "foo")]
mod foo {
}Run

Если скомпилировать его с помощью cargo build --features "foo", то в rustc будет передан флаг --cfg feature="foo", и результат будет содержать модуль mod foo. Если скомпилировать его с помощью обычной команды cargo build, то никаких дополнительных флагов передано не будет, и поэтому, модуль mod foo будет отсутствовать.

cfg_attr

Вы также можете установить другой атрибут в зависимости от переменной cfg с помощью атрибута cfg_attr:

#[cfg_attr(a, b)]Run

Этот код будет равносилен атрибуту #[b], если в атрибуте cfg установлен флаг a, или «без атрибута» в противном случае.

cfg!

Расширение синтаксиса cfg! позволяет использовать данные виды флагов и в другом месте в коде:

if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
    println!("Think Different!");
}Run

Значение флага будет заменено на true или false во время компиляции, в зависимости от настройки конфигурации.