Атрибуты

В Rust объявления могут быть аннотированы с помощью «атрибутов». Они выглядят так:

fn main() { #[test] fn foo() {} }
#[test]

или так:

fn main() { mod foo { #![test] } }
#![test]

Разница между ними состоит в символе !, который изменяет его поведение, определяющее к какому элементу применяется атрибут:

fn main() { #[foo] struct Foo; mod bar { #![bar] } }
#[foo]
struct Foo;

mod bar {
    #![bar]
}

Атрибут #[foo] относится к следующему за ним элементу, который является объявлением struct. Атрибут #![bar] относится к элементу охватывающему его, который является объявлением mod. В остальном они одинаковы. Оба каким-то образом изменяют значение элемента, к которому они прикреплены.

Например, рассмотрим такую функцию:

fn main() { #[test] fn check() { assert_eq!(2, 1 + 1); } }
#[test]
fn check() {
    assert_eq!(2, 1 + 1);
}

Функция помечена как #[test]. Это означает, что она особенная: эта функция будет выполняться при запуске тестов. При компиляции, как правило, она не будет включена. Теперь эта функция является функцией тестирования.

Атрибуты также могут иметь дополнительные данные:

fn main() { #[inline(always)] fn super_fast_fn() { } }
#[inline(always)]
fn super_fast_fn() {

Или даже ключи и значения:

fn main() { #[cfg(target_os = "macos")] mod macos_only { } }
#[cfg(target_os = "macos")]
mod macos_only {

Атрибуты в Rust используются для ряда различных вещей. Вот ссылка на полный список атрибутов. В настоящее время вы не можете создавать свои собственные атрибуты, компилятор Rust определяет их.