属性 Attributes
如果属性对整个 crate 都有作用的话, 使用 #![crate_attribute] 写法; 如果只对当前
module, 某个函数等起作用的话, 使用 #[module_attribute] 写法.
设置整个 crate 的属性 #![crate_attribute]; 设置整个 module 的属性, #[crate_attribute], 少了一个 ! 号.
它多种语法形式:
| 语法 | 描述 | 示例 |
|---|---|---|
#[attribute = "value"] | 设定属性值 | #![crate_type = "lib"] |
#[attribute(key = "value")] | key-value 形式, 键值对 | #![cfg(target_os = "linux")] |
#[attribute(value)] | 单个标识符 | #[allow(dead_code)], 对某个模块及函数禁用 dead_code lint |
接下来, 我们介绍一些常用的属性设置.
inline
用于提示 rustc 编译器, 把该函数标记为内联函数(inline function).
所谓的内联函数, 就是把函数体内的代码直接插入到该函数的调用处, 这样可以在代码里减少一个函数调用的成本.
看下面的一个示例代码, 注释部分是编译器可能生成的代码, 它会将 Point 中定义的函数体直接展开:
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct Point {
x: i32,
y: i32,
}
impl Default for Point {
fn default() -> Self {
Self::new()
}
}
impl Point {
#[must_use]
#[inline]
pub const fn new() -> Self {
Self { x: 0, y: 0 }
}
#[must_use]
#[inline]
pub const fn from_xy(x: i32, y: i32) -> Self {
Self { x, y }
}
#[inline]
pub fn set_x(&mut self, x: i32) {
self.x = x;
}
#[inline]
pub fn set_y(&mut self, y: i32) {
self.y = y;
}
#[must_use]
#[inline]
pub const fn x(&self) -> i32 {
self.x
}
#[must_use]
#[inline]
pub const fn y(&self) -> i32 {
self.y
}
}
fn main() {
// let mut point: Point = Point {x: 3, y: 4};
let mut point: Point = Point::from_xy(3, 4);
// point.x = 2;
point.set_x(2);
// let y: i32 = point.y;
let y: i32 = point.y();
println!("y: {y}");
}
除了上面的默认写法之外, 还有另外两种写法:
#[inline(always)], 建议编译器总是把该函数内联#[inline(never)], 建议编译器不把该函数内联
比如标准库里的 Backtrace::capture() 函数, 它就提示编译器不要做内联.
// From: std/src/backtrace.rs
/// Capture a stack backtrace of the current thread.
///
/// ...
///
#[stable(feature = "backtrace", since = "1.65.0")]
#[inline(never)] // want to make sure there's a frame here to remove
pub fn capture() -> Backtrace {
if !Backtrace::enabled() {
return Backtrace { inner: Inner::Disabled };
}
Backtrace::create(Backtrace::capture as usize)
}