Rust 中的属性详解
Rust 中的属性是什么?属性(Attribute)是一种通用的自由格式的元数据,Rust 中的属性以 ECMA-335 中的为模型,其语法则来自 ECMA-334(C#)。
1. 属性的用途
属性只能应用于 Rust 中的项(Item),属性的主要用途如下:
- 条件编译
- 设置 Crate 名称,版本和类型(binary 或 library)
- 自动生成代码
- 控制 Linter 的行为
- 启用编译器的一些特性
- 链接外部的 library
- 标记单元测试函数
2. 属性的语法
属性的语法借鉴了 C#,内部属性(Inner attributes)以 #! 开头,外部属性(Outer attributes)则以 # 开头。内部属性应用于它所在的项(Item),外部属性应用于紧跟在它之后的项(Item)。
属性中的参数支持不同的语法形式,比如:
#[no_std] #[doc = "example"] #[allow(unused, clippy::inline_always)] #[macro_use(foo, bar)] #[link(name = "CoreFoundation", kind = "framework")]
3. 属性的分类
属性可以被分为以下四类:
4. 常用的属性
Test
test 属性用来把一个函数标记为单元测试函数,这些函数只有在测试模式下(cargo test或rustc --test)才会被编译。测试函数没有参数,并且返回值类型必须是以下两种:
- ()
- Result<(), E> where E: Error
示例:
#[test] fn test_the_thing() -> io::Result<()> { let state = setup_the_thing()?; do_the_thing(&state)?; Ok(()) }
Derive
derive 属性一般用来为数据类型生成 Trait 实现。
示例:
#[derive(PartialEq, Clone)] struct Foo<T> { a: i32, b: T, }
编译器会自动为 Foo 生成 PartialEq 的实现:
impl<T: PartialEq> PartialEq for Foo<T> { fn eq(&self, other: &Foo<T>) -> bool { self.a == other.a && self.b == other.b } fn ne(&self, other: &Foo<T>) -> bool { self.a != other.a || self.b != other.b } }
目前 derive 仅支持标准库中部分的 Trait,我们也可以通过 procedural macros 来为自己的 Trait 实现 derive。其实,标准库里也是通过这种方式实现的,比如:Debug。
5. 相关资料
Attributes - The Rust Reference
Pin<P> 这是一个struct,作用就是将P所指向的T在内存中固定住,不能移动。说白一些,就是不能通过safe代码拿到&mut T。 Pin定义如下: pub struct Pin< ...