PhantomData 的例子、用途

例子:

例子如下:

bash 复制代码
cargo new demo
cd demo

修改 main.rs 如下:

rust 复制代码
use std::marker::PhantomData;
use std::any::type_name;

// 一个空标记结构体,用来打印类型
struct TypePrinter<T> {
    // 只用来"携带"类型 T,不占内存
    _phantom: PhantomData<T>,
}

impl<T> TypePrinter<T> {
    // 创建一个打印专用实例
    fn new() -> Self {
        Self {
            _phantom: PhantomData,
        }
    }

    // 打印当前携带的类型名字
    fn print_type(&self) {
        println!("当前类型:{}", type_name::<T>());
    }
}

fn main() {
    // 打印 i32 类型
    let p1 = TypePrinter::<i32>::new();
    p1.print_type();

    // 打印 String 类型
    let p2 = TypePrinter::<String>::new();
    p2.print_type();

    // 打印 &str 类型
    let p3 = TypePrinter::<&str>::new();
    p3.print_type();

    // 打印 Vec<bool> 类型
    let p4 = TypePrinter::<Vec<bool>>::new();
    p4.print_type();
}

运行下面的命令:

bash 复制代码
cargo run

预期输出:

复制代码
当前类型:i32
当前类型:alloc::string::String
当前类型:&str
当前类型:alloc::vec::Vec<bool>

解析 PhantomData

PhantomData 是 Rust 标准库 std::marker 中的一个零大小类型(ZST),它不占用运行时内存,但能在编译期向编译器传递关键的类型语义信息,用于表达逻辑关联、约束生命周期或控制类型行为。

PhantomData 本身没内存、没字段、不占空间,只是骗 / 告诉编译器:

「我这个结构体,逻辑上关联了某个泛型 / 生命周期」

不然编译器会报错:泛型参数没用到、生命周期没用上。

口诀:

泛型用不到,编译器发飙;

加个 PhantomData,安静又达标。

问题:凭什么会需要「只有类型、没有数据」?正常写代码不都是字段存数据吗?

回答:例子场景如下:

两种「长得一样,但绝对不能混用」的 ID

UserId

OrderId

底层都是 u64,数值完全一样。

如果直接写:

rust 复制代码
struct Id(u64);

用户ID 能直接传给「删除订单」接口,出线上事故。

解决方案:只挂类型标签,不加数据

rust 复制代码
use std::marker::PhantomData;

struct User;
struct Order;

// 只有一个数值 + 一个空类型标记,没有任何额外数据
struct Id<T>(u64, PhantomData<T>);

fn fetch_user(id: Id<User>) {}
fn delete_order(id: Id<Order>) {}

运行时只存一个 u64,不能多存东西;

但编译期必须是两种完全不同的类型,防止传参搞错。

这就是:只带类型、不带内容 的刚需。

这也是 RUST 确保内存安全的方式之一。

相关推荐
对象存储与RustFS2 小时前
用 rclone 把现有 S3/MinIO 数据同步到 RustFS
后端·rust·开源
2501_915918415 小时前
Rust 程序抓包解密,rustls 不认系统证书的几种办法
开发语言·后端·网络协议·ios·adb·https·rust
学心理学的程序员5 小时前
anydoc:Firecrawl 出的 Rust 文档转 Markdown,4ms 转换、14 种格式干翻 MarkItDown
开发语言·后端·rust·开源·firecrawl·claude code·anydoc
Flynt18 小时前
OpenAI把Codex底层从TS重写成Rust,我拆开看了下它的三层架构
rust·openai·agent
第一程序员19 小时前
AI 辅助编程的 7 个误区:把模型当高级搜索引擎是对它的最大浪费
python·rust·github
NutShell Wang1 天前
Firecrawl anydoc 实战拆解:用一个 Rust 依赖吃下 14 种文档格式
性能优化·rust·vibe coding
DevHub1 天前
probe-rs 教程:一行命令替代 OpenOCD 烧写调试 Cortex-M
arm开发·嵌入式硬件·mcu·rust
程序员爱钓鱼1 天前
Rust const泛型详解:让常量也成为泛型参数
后端·面试·rust
k4m7v2pz1 天前
ESP32-S3 + I2S 麦克风实时音频流静音问题排查:从网络到AGC的谬误溯源
rust·音频·esp32·agc·实时监听·静音排查
SomeB1oody1 天前
【RustyML入门】7.4. 按需裁剪与模块化集成
开发语言·后端·机器学习·rust·教程