属性

语法
内部属性 :
   # ! [ Attr ]

外部属性 :
   # [ Attr ]

属性 (Attr) :
      简单路径 属性输入?
   | unsafe ( 简单路径 属性输入? )

属性输入 (AttrInput) :
      分隔符令牌树 (DelimTokenTree)
   | = 表达式

一个属性是一种通用、自由形式的元数据,根据名称、惯例、语言和编译器版本进行解释。属性的建模基于 ECMA-335 中的 Attributes,而语法来源于 ECMA-334 (C#)。

内部属性,写在井号(#)后加感叹号(!),应用于声明该属性的项目(item)内部。外部属性,写在井号后不加感叹号,应用于属性后面的项。

属性由属性路径组成,后跟一个可选的分隔符令牌树,其解释由属性定义。除了宏属性之外的属性也允许输入是一个等号(=)后跟一个表达式。更多详情请参阅下面的 元项语法

应用某个属性可能不安全。为了避免使用这些属性时出现未定义行为,必须满足编译器无法检查的某些义务。为声明这些义务已满足,属性被包裹在 unsafe(..) 中,例如 #[unsafe(no_mangle)]

以下属性是不安全的

属性可以分为以下几种类型

属性可以应用于语言中的许多地方

属性的一些示例

#![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)
   | 简单路径 = 表达式
   | 简单路径 ( 元序列? )

元序列 (MetaSeq) :
   内部元项 ( , 内部元项 )* ,?

内部元项 (MetaItemInner) :
      元项 (MetaItem)
   | 表达式

元项中的表达式必须宏展开为字面量表达式,字面量表达式不得包含整数或浮点类型后缀。非字面量表达式在语法上会被接受(并且可以传递给过程宏),但会在解析后被拒绝。

请注意,如果属性出现在另一个宏内部,它将在外部宏之后展开。例如,以下代码会先展开 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):
   标识符 (IDENTIFIER)

元名称值字符串 (MetaNameValueStr):
   标识符 = (字符串字面量 | 原始字符串字面量)

元列表路径 (MetaListPaths):
   标识符 ( ( 简单路径 (, 简单路径)* ,? )? )

元列表标识符 (MetaListIdents):
   标识符 ( ( 标识符 (, 标识符)* ,? )? )

元列表名称值字符串 (MetaListNameValueStr):
   标识符 ( ( 元名称值字符串 (, 元名称值字符串)* ,? )? )

一些元项示例包括

样式示例
元词 (MetaWord)no_std
元名称值字符串 (MetaNameValueStr)doc = "example"
元列表路径 (MetaListPaths)allow(unused, clippy::inline_always)
元列表标识符 (MetaListIdents)macro_use(foo, bar)
元列表名称值字符串 (MetaListNameValueStr)link(name = "CoreFoundation", kind = "framework")

活跃属性和惰性属性

属性分为活跃属性或惰性属性。在属性处理期间,活跃属性会从其所附着的项中移除自身,而惰性属性会保留。

cfgcfg_attr 属性是活跃的。属性宏 是活跃的。所有其他属性都是惰性的。

工具属性

编译器可能允许用于外部工具的属性,其中每个工具都驻留在 工具 prelude 中的自己的模块中。属性路径的第一个部分是工具的名称,后跟一个或多个附加部分,其解释取决于工具。

当某个工具未使用时,该工具的属性会被接受而不会产生警告。当该工具正在使用时,该工具负责处理和解释其属性。

如果使用了 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”, “miri” 和 “rust_analyzer”。

内置属性索引

以下是所有内置属性的索引。

  • 条件编译

    • cfg — 控制条件编译。
    • cfg_attr — 条件性地包含属性。
  • 测试

    • test — 将函数标记为测试。
    • ignore — 禁用测试函数。
    • should_panic — 指示测试应产生 panic。
  • 派生

  • 诊断

  • ABI、链接、符号和 FFI

    • link — 指定一个原生库以与 extern 块链接。
    • link_name — 指定 extern 块中函数或静态量的符号名称。
    • link_ordinal — 指定 extern 块中函数或静态量的符号序号 (ordinal)。
    • no_link — 阻止链接外部 crate。
    • repr — 控制类型布局。
    • crate_type — 指定 crate 类型(库、可执行文件等)。
    • no_main — 禁用发出 main 符号。
    • export_name — 指定函数或静态量的导出符号名称。
    • link_section — 指定目标文件中用于函数或静态量的节 (section)。
    • no_mangle — 禁用符号名称编码 (mangle)。
    • used — 强制编译器在输出目标文件中保留静态项。
    • crate_name — 指定 crate 名称。
  • 代码生成

    • inline — 内联代码的提示。
    • cold — 提示函数不太可能被调用。
    • no_builtins — 禁用某些内置函数的使用。
    • target_feature — 配置平台特定的代码生成。
    • track_caller — 将父调用位置传递给 std::panic::Location::caller()
    • instruction_set — 指定用于生成函数代码的指令集
  • 文档

  • 预导入 (Preludes)

  • 模块

    • path — 指定模块的文件名。
  • 限制

  • 运行时

  • 特性

    • feature — 用于启用不稳定或实验性编译器特性。关于在 rustc 中实现的特性,请参阅 不稳定手册
  • 类型系统

    • non_exhaustive — 指示某个类型将来会添加更多字段/变体。
  • 调试器