属性
语法
内部属性 :
#
!
[
Attr]
外部属性 :
#
[
Attr]
Attr :
简单路径 AttrInput?
属性 是一种通用的、自由形式的元数据,根据名称、约定、语言和编译器版本进行解释。属性的模型是 ECMA-335 中的属性,语法来自 ECMA-334 (C#)。
内部属性,在井号 (#
) 后面写一个感叹号 (!
),应用于声明该属性的项。外部属性,在井号后面没有感叹号,应用于属性后面的内容。
属性由属性的路径组成,后面跟着一个可选的分隔符词法树,其解释由属性定义。宏属性以外的属性还允许输入是一个等号 (=
),后面跟着一个表达式。有关更多详细信息,请参阅下面的 元项语法。
属性可以分为以下几种
属性可以应用于语言中的许多内容
- 所有 项声明 都接受外部属性,而 外部块、函数、实现 和 模块 接受内部属性。
- 大多数 语句 都接受外部属性(有关表达式语句的限制,请参阅 表达式属性)。
- 块表达式 接受外部和内部属性,但前提是它们是 表达式语句 的外部表达式或另一个块表达式的最终表达式。
- 枚举 变体以及 结构体 和 联合体 字段接受外部属性。
- Match 表达式分支 接受外部属性。
- 泛型生命周期或类型参数 接受外部属性。
- 表达式在有限的情况下接受外部属性,有关详细信息,请参阅 表达式属性。
- 函数、闭包 和 函数指针 参数接受外部属性。这包括函数指针和 外部块 中用
...
表示的可变参数的属性。
一些属性示例
#![allow(unused)] fn main() { // General metadata applied to the enclosing module or crate. #![crate_type = "lib"] // A function marked as a unit test #[test] fn test_foo() { /* ... */ } // A conditionally-compiled module #[cfg(target_os = "linux")] mod bar { /* ... */ } // A lint attribute used to suppress a warning/error #[allow(non_camel_case_types)] type int8_t = i8; // Inner attribute applies to the entire function. fn some_unused_variables() { #![allow(unused_variables)] let x = (); let y = (); let z = (); } }
元项属性语法
“元数据项”是大多数内置属性用于 Attr 规则的语法。它具有以下语法
语法
MetaItem :
SimplePath
| SimplePath=
Expression
| SimplePath(
MetaSeq?)
MetaSeq :
MetaItemInner (,
MetaItemInner )*,
?MetaItemInner :
MetaItem
| Expression
元数据项中的表达式必须宏展开为字面表达式,并且不能包含整数或浮点类型后缀。非字面表达式的表达式将在语法上被接受(并且可以传递给过程宏),但在解析后会被拒绝。
请注意,如果属性出现在另一个宏中,则它将在该外部宏之后展开。例如,以下代码将首先展开 Serialize
过程宏,该宏必须保留 include_str!
调用才能展开
#[derive(Serialize)]
struct Foo {
#[doc = include_str!("x.md")]
x: u32
}
此外,属性中的宏只会在应用于该项的所有其他属性之后展开
#[macro_attr1] // expanded first
#[doc = mac!()] // `mac!` is expanded fourth.
#[macro_attr2] // expanded second
#[derive(MacroDerive1, MacroDerive2)] // expanded third
fn foo() {}
各种内置属性使用元数据项语法的不同子集来指定其输入。以下语法规则显示了一些常用形式
语法
MetaWord:
IDENTIFIERMetaNameValueStr:
IDENTIFIER=
(STRING_LITERAL | RAW_STRING_LITERAL)MetaListPaths:
IDENTIFIER(
( SimplePath (,
SimplePath)*,
? )?)
MetaListIdents:
IDENTIFIER(
( IDENTIFIER (,
IDENTIFIER)*,
? )?)
MetaListNameValueStr:
IDENTIFIER(
( MetaNameValueStr (,
MetaNameValueStr)*,
? )?)
以下是元数据项的一些示例
样式 | 示例 |
---|---|
MetaWord | no_std |
MetaNameValueStr | doc = "example" |
MetaListPaths | allow(unused, clippy::inline_always) |
MetaListIdents | macro_use(foo, bar) |
MetaListNameValueStr | link(name = "CoreFoundation", kind = "framework") |
活动和惰性属性
属性可以是活动的,也可以是惰性的。在属性处理过程中,活动属性会从它们所在的位置移除自身,而惰性属性则会保留。
cfg
和 cfg_attr
属性是活动的。test
属性在编译测试时是惰性的,否则是活动的。属性宏是活动的。所有其他属性都是惰性的。
工具属性
编译器可以允许外部工具使用属性,其中每个工具都位于工具前奏中的自己的命名空间中。属性路径的第一段是工具的名称,后面是一个或多个附加段,其解释由工具决定。
当一个工具没有被使用时,该工具的属性会被接受,并且不会发出警告。当工具正在使用时,该工具负责处理和解释其属性。
如果使用了 no_implicit_prelude
属性,则工具属性不可用。
#![allow(unused)] fn main() { // Tells the rustfmt tool to not format the following element. #[rustfmt::skip] struct S { } // Controls the "cyclomatic complexity" threshold for the clippy tool. #[clippy::cyclomatic_complexity = "100"] pub fn f() {} }
注意:
rustc
当前识别工具“clippy”、“rustfmt”和“diagnostic”。
内置属性索引
以下是所有内置属性的索引。
- 条件编译
- 测试
test
— 将函数标记为测试。ignore
— 禁用测试函数。should_panic
— 指示测试应该生成一个恐慌。
- 派生
derive
— 自动实现特征。automatically_derived
— 由derive
创建的实现的标记。
- 宏
macro_export
— 导出macro_rules
宏以供跨箱使用。macro_use
— 扩展宏可见性,或从其他箱导入宏。proc_macro
— 定义类似函数的宏。proc_macro_derive
— 定义派生宏。proc_macro_attribute
— 定义属性宏。
- 诊断
allow
、warn
、deny
、forbid
— 更改默认的 lint 级别。deprecated
— 生成弃用通知。must_use
— 为未使用值生成 lint。diagnostic::on_unimplemented
— 提示编译器在未实现特征时发出特定的错误消息。
- ABI、链接、符号和 FFI
link
— 指定要与extern
块链接的原生库。link_name
— 指定extern
块中函数或静态变量的符号名称。link_ordinal
— 指定extern
块中函数或静态变量的符号序号。no_link
— 防止链接外部箱。repr
— 控制类型布局。crate_type
— 指定箱的类型(库、可执行文件等)。no_main
— 禁用发出main
符号。export_name
— 指定函数或静态变量的导出符号名称。link_section
— 指定用于函数或静态变量的目标文件部分。no_mangle
— 禁用符号名称编码。used
— 强制编译器在输出目标文件中保留静态项。crate_name
— 指定箱名称。
- 代码生成
inline
— 提示内联代码。cold
— 提示函数不太可能被调用。no_builtins
— 禁用某些内置函数的使用。target_feature
— 配置特定于平台的代码生成。track_caller
- 将父调用位置传递给std::panic::Location::caller()
。instruction_set
- 指定用于生成函数代码的指令集
- 文档
doc
— 指定文档。有关详细信息,请参阅Rustdoc 书籍。文档注释会被转换为doc
属性。
- 前奏
no_std
— 从前奏中移除 std。no_implicit_prelude
— 禁用模块内的前奏查找。
- 模块
path
— 指定模块的文件名。
- 限制
recursion_limit
— 设置某些编译时操作的最大递归限制。type_length_limit
— 设置多态类型的最大大小。
- 运行时
panic_handler
— 设置处理恐慌的函数。global_allocator
— 设置全局内存分配器。windows_subsystem
— 指定要链接的 Windows 子系统。
- 特性
feature
— 用于启用不稳定或实验性的编译器特性。有关rustc
中实现的特性,请参阅不稳定特性书籍。
- 类型系统
non_exhaustive
— 指示类型将在将来添加更多字段/变体。
- 调试器
debugger_visualizer
— 嵌入一个文件,该文件指定类型的调试器输出。