What are Rust's attributes?
Declarations can be annotated with attributes
in Rust.
In essence, they attach some meta-data to a declaration which can be later used by the compiler to achieve some functionality.
To better understand this, consider the following example.
// Marking a function for testing.
#[test]
fn test_myFunction() {
/* ... */
}
The #[test]
attribute will mark the function test_myFunction
for testing. So, when you normally compile and run this program, this function will not be built.
Whereas, is you run the cargo test
command, it will be executed.
Ways to add attributes
There are mainly 2 ways to add attributes.
- Using
#[<attribute_description>]
-> Applies to the next item. - Using
#![<attribute_description>]
-> Applies to the item enclosing it.
For example,
#[attribute1]
struct myStruct;
mod myModule {
#![attribute2]
}
Here, the attribute1
is applied to myStruct
and the attribute2
is applied to myModule
.
Examples of usage
An OS-specific module
#[cfg(target_os = "macos")]
mod macos_module {
}
This module would only compile on a Mac operating system.
Async functionality using custom runtimes
use tokio::io::{stdout, AsyncWriteExt as _};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
}
This would inform the Rust compiler to execute the main function using the Tokio runtime.