You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

tokio::pin!与std::pin::pin!的区别及选型指南

tokio::pin! 与 std::pin::pin! 的区别及选择指南

核心差异

1. 对 Unpin 类型的处理逻辑

  • std::pin::pin! 是标准库的基础宏,不管传入的类型是否实现 Unpin,都会强制生成 Pin<&mut T> 类型的固定引用,没有额外适配逻辑。
  • tokio::pin! 在标准库宏的基础上做了优化:如果传入的类型本身是 Unpin(比如 String、Vec 这类无需固定的类型),它会直接返回普通的 &mut T 可变引用,跳过不必要的 Pin 包装,减少冗余操作。

2. 适用场景区分

  • std::pin::pin!:适用于非 Tokio 环境的异步代码,或者需要严格遵循标准库行为的场景。比如使用基础 futures 库编写通用异步逻辑,或明确需要固定非 Unpin 类型时,用它就足够。
  • tokio::pin!:专为 Tokio 生态设计,在 Tokio 项目中编写异步代码时优先使用。它能自动识别并适配 Unpin 类型,省去手动判断类型是否需要固定的麻烦,代码更简洁。比如处理 Tokio 提供的各种 Future 对象时,不管其是否为 Unpin,用这个宏都能统一处理。

代码示例对比

处理 Unpin 类型

use std::pin::pin;
use tokio::pin;

let mut x = String::from("hello");

// std::pin::pin! 生成 Pin<&mut String>,需调用 as_mut() 获取可变引用
let mut pinned_std = pin!(x);
pinned_std.as_mut().push_str(" world");

// tokio::pin! 直接生成 &mut String,可直接操作
let mut pinned_tokio = pin!(x);
pinned_tokio.push_str(" world");

处理非 Unpin 类型(如 async 块)

use std::pin::pin;
use tokio::pin;

let fut = async { println!("hello"); };

// 两种宏行为一致,均生成 Pin<&mut impl Future>
let mut pinned_std = pin!(fut);
let mut pinned_tokio = pin!(fut);

选择原则

  • 如果你在 Tokio 项目中开发,直接用 tokio::pin!,它的适配性更强,能简化代码。
  • 如果你写的是不依赖 Tokio 的通用异步代码,或者需要严格匹配标准库行为,就用 std::pin::pin!。

内容的提问来源于stack exchange,提问作者bli00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:04:52