Выбрать главу

Атрибуты — это метаданные, применяемые к какому-либо модулю, контейнеру или их элементу. Благодаря атрибутам можно:

   • задать условия компиляции кода

   • задать имя, версию и тип (библиотека или исполняемый файл) контейнера

   • отключить проверки (lints)

   • включить возможности компилятора (макросы, глобальный импорт и другое)

   • линковаться с внешней библиотекой

   • пометить функции как модульные тесты

   • пометить функции, которые будут частью теста производительности

Когда атрибуты применяются ко всему контейнеру, их синтаксис будет #![crate_attribute], а когда они применяются к модулю или элементу модуля, их синтаксис станет #[item_attribute] (обратите внимание на отсутствие !).

Атрибуты могут принимать аргументы с различным синтаксисом:

   • #[attribute = "value"]

   • #[attribute(key = "value")]

   • #[attribute(value)]

Атрибуты могут иметь несколько значений и быть разделены несколькими строками:

#[attribute(value, value2)]

#[attribute(value, value2, value3,

value4, value5)]

Компилятор предоставляет проверку dead_code, которая предупреждает о неиспользованных функциях. Атрибут dead_code можно использовать, чтобы отключить данную проверку.

fn used_function() {}

// `#[allow(dead_code)]` — атрибут, который убирает проверку на неиспользуемый код

#[allow(dead_code)]

fn unused_function() {}

fn noisy_unused_function() {}

// FIXME ^ Добавьте атрибут `dead_code`, чтобы убрать предупреждение

fn main() {

used_function();

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Обратите внимание, что в реальных программах вы должны удалить неиспользуемый код. В этих примерах мы разрешаем оставить неиспользуемый код в некоторых местах — но это только для примера!

Атрибут crate_type используется, чтобы сказать компилятору, какой контейнер является библиотекой (и каким типом библиотеки), а какой — исполняемым файлом. Атрибут crate_name используется для указания имени контейнера.

Однако важно отметить, что атрибуты crate_type и create_name не имеют значения при использовании пакетного менеджера Cargo. В виду того, что Cargo используется для большинства проектов на Rust, в реальном мире использование crate_type и crate_name достаточно ограничено.

// Этот контейнер - библиотека

#![crate_type = "lib"]

// Эта библиотека называется "rary"

#![crate_name = "rary"]

pub fn public_function() {

println!("вызвана `public_function()` библиотеки `rary`");

}

fn private_function() {

println!("вызвана `private_function()` библиотеки `rary`");

}

pub fn indirect_access() {

print!("вызвана `indirect_access()` библиотеки `rary`, и в ней\n> ");

private_function();

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Если мы используем атрибут crate_type, то нам больше нет необходимости передавать компилятору флаг --crate-type.

$ rustc lib.rs

$ ls lib*

library.rlib

cfg

Условная конфигурация возможна при помощи двух разных операторов:

   • атрибута cfg: #[cfg(...)], который указывается на месте атрибута

   • макроса cfg!: cfg!(...), который можно использовать в условных выражениях

В то время как первый атрибут включает условную компиляцию, второй преобразуется в литералы true или false, позволяя сделать проверку во время исполнения. Оба варианта используют идентичный синтаксис для аргументов.

// Эта функция будет скомпилирована только в том случае, если целевая ОС будет linux

#[cfg(target_os = "linux")]

fn are_you_on_linux() {

println!("Вы работаете в linux!");