属性 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)
}