《通过例子学Rust》第13章 属性

属性是应用于某些模块、crate 或项的元数据(metadata)。这元数据可以用来:

当属性作用于整个 crate 时,它们的语法为 #![crate_attribute],当它们用于模块或项时,语法为 #[item_attribute](注意少了感叹号 !)。

属性可以接受参数,有不同的语法形式:

  • #[attribute = "value"]
  • #[attribute(key = "value")]
  • #[attribute(value)]

属性可以多个值,它们可以分开到多行中:

复制代码
#[attribute(value, value2)]

#[attribute(value, value2, value3,
            value4, value5)]

13.1 死代码 dead_code

编译器提供了 dead_code(死代码,无效代码)lint,这会对未使用的函数产生警告。可以用一个属性来禁用这个 lint。

复制代码
// 13.1节 死代码dead_code
fn used_function() {
    println!("call used_function()");
}

// `#[allow(dead_code)]` 属性可以禁用 `dead_code` lint
#[allow(dead_code)]
fn unused_functin() {}

#[allow(dead_code)]
fn noisy_unused_function() {}
// 改正 ^ 增加一个属性来消除警告

fn main() {
    used_function();

    println!("Hello Rust"); 
}

// rustc main.rs  
// ./main

编译运行:

复制代码
PS F:\rustproject\rustbyexample\chapter13\example13_1> rustc main.rs
PS F:\rustproject\rustbyexample\chapter13\example13_1> ./main
call used_function()
Hello Rust
PS F:\rustproject\rustbyexample\chapter13\example13_1>

注意在实际程序中,需要将死代码清除掉。由于本书的例子是交互性的,因而其中需要允许一些死代码的出现。

13.2 crate

crate_type 属性可以告知编译器 crate 是一个二进制的可执行文件还是一个库(甚至是哪种类型的库),crate_name 属性可以设定 crate 的名称。

不过,一定要注意在使用 cargo 时,这两种类型时都没有 作用。由于大多数 Rust 工程都使用 cargo,这意味着 crate_typecrate_name 的作用事实上很有限。

复制代码
// 13.2节 crate
// 这个 crate 是一个库文件
#![crate_type = "lib"]
// 库的名称为 "rary"
#![crate_name = "rary"]

pub fn public_function() {
    println!("called rary's  'public_function()'");
}

fn private_function() {
    println!("called rary's 'private_function()'");
}

pub fn indirect_access() {
    print!("called rary's 'indirect_access()', that\n> ");
    private_function();
}

// rustc lib.rs 
// ls lib*

当用到 crate_type 属性时,就不再需要给 rustc 命令加上 --crate-type 标记。

复制代码
PS F:\rustproject\rustbyexample\chapter13\example13_2>  rustc lib.rs
PS F:\rustproject\rustbyexample\chapter13\example13_2>  ls lib*
library.rlib

13.3 cfg

条件编译可能通过两种不同的操作符实现:

  • cfg 属性:在属性位置中使用 #[cfg(...)]
  • cfg! 宏:在布尔表达式中使用 cfg!(...)

两种形式使用的参数语法都相同。

复制代码
// 13.3节 cfg
// 这个函数仅当目标系统是 Linux 的时候才会编译
#[cfg(target_os = "linux")]
fn are_you_on_linux() {
    println!("You are running linux!")
}

// 而这个函数仅当目标系统 **不是** Linux 时才会编译
#[cfg(not(target_os = "linux"))]
fn are_you_on_linux() {
    println!("You are *not* running linux!")
}

fn main() {
    are_you_on_linux();
    println!("Are you sure?");
    if cfg!(target_os = "linux") {
        println!("Yes. It's definitely linux!");
    } else {
        println!("Yes. It's definitely *not* linux!");
    }

    if cfg!(target_os = "windows") {
        println!("this is windows OS!");
    } else {
        println!("this not is windows OS!");
    }

    println!("Hello Rust"); 
}

// rustc main.rs  
// ./main

编译运行:

复制代码
PS F:\rustproject\rustbyexample\chapter13\example13_3> rustc main.rs
PS F:\rustproject\rustbyexample\chapter13\example13_3> ./main
You are *not* running linux!
Are you sure?
Yes. It's definitely *not* linux!
this is windows OS!
Hello Rust
PS F:\rustproject\rustbyexample\chapter13\example13_3>
参见:

引用, cfg!, 和 .

13.3.1 自定义条件

有部分条件如 target_os 是由 rustc 隐式地提供的,但是自定义条件必须使用 --cfg 标记来传给 rustc

复制代码
// 13.3.1节 自定义条件
#[cfg(some_condition)]
fn conditional_function() {
    println!("condition met!")
}

fn main() {
    conditional_function();
    println!("Hello Rust");
}

// rustc --cfg some_condition main.rs  
// ./main

试试不使用自定义的 cfg 标记会发生什么:

复制代码
PS F:\rustproject\rustbyexample\chapter13\example13_4> rustc main.rs
error[E0425]: cannot find function `conditional_function` in this scope
 --> main.rs:8:5
  |
8 |     conditional_function();
  |     ^^^^^^^^^^^^^^^^^^^^ not found in this scope
  |
note: found an item that was configured out
 --> main.rs:3:4
  |
2 | #[cfg(some_condition)]
  |       -------------- the item is gated here
3 | fn conditional_function() {
  |    ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0425`.
PS F:\rustproject\rustbyexample\chapter13\example13_4>

使用自定义的 cfg 标记:

复制代码
PS F:\rustproject\rustbyexample\chapter13\example13_4> rustc --cfg some_condition main.rs
PS F:\rustproject\rustbyexample\chapter13\example13_4> ./main
condition met!
Hello Rust
PS F:\rustproject\rustbyexample\chapter13\example13_4> 
相关推荐
梦醒沉醉12 小时前
4、Rust参考手册——Crate和源文件
rust
chainbees12 小时前
Windows 系统 Rust 运行环境搭建
rust
k4m7v2pz15 小时前
从 Python 搬到 Rust:pyglet MIDI DAW 变成 egui 鬼畜采样器的迁移复盘
开发语言·python·rust
小灰灰搞电子16 小时前
Rust+Slint 实现ModbusRTU从机调试助手源码分享
开发语言·rust·modbusrtu
Source.Liu18 小时前
Tauri 2.0 + Alpine.js 起步笔记(零构建方案)
rust
小灰灰搞电子18 小时前
Rust+Slint 实现抽屉式侧边栏源码分享
开发语言·rust·侧边栏
码艺-Alimjan19 小时前
Tauri 2.x + Vue 3 桌面应用开发实战:从踩坑到完美落地
前端·javascript·vue.js·rust·typescript·go
右耳朵猫AI20 小时前
Node.js周刊2026W36 | NestJS 12发布、Remix 3 RC、pnpm 12 Rust重写、Node.js 26.8.0
开发语言·rust·node.js
右耳朵猫AI20 小时前
Web前端周刊2026W36 | pnpm 12 Rust 重写、Remix 3 RC、Node.js 26.8.0、htmx 4.0 大版本
前端·rust·node.js