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

为何&i32在不同场景下有时实现Unpin trait有时却不实现?

Rust中Pin::new调用的编译差异问题解析

先看这段Rust代码:

use std::pin::Pin;

fn main() {
    let val: i32 = 3;

    let val_pin = Pin::new(&val);
    f(val_pin);

    f(Pin::new(&val));
}

fn f(_val: Pin<&dyn TestTrait>) {}

trait TestTrait {}

impl TestTrait for i32 {}

这段代码里,第6行let val_pin = Pin::new(&val);能正常编译,但第9行直接把Pin::new(&val)传给f却触发编译错误,错误信息如下:

error[E0277]: `dyn TestTrait` cannot be unpinned
   --> src/main.rs:9:7
    |
9   |     f(Pin::new(&val));
    |       ^^^^^^^^ the trait `Unpin` is not implemented for `dyn TestTrait`
    |
    = note: consider using `Box::pin`
note: required by a bound in `Pin::&lt;P&gt;::new`
   --> /usr/lib/rustlib/src/rust/library/core/src/pin.rs:482:23
    |
482 | impl<P: Deref<Target: Unpin>> Pin<P> {
    |                       ^^^^^ required by this bound in `Pin::new`

原因解析

核心差异在于类型推导的时机和目标不同:

  • 第6行:Pin::new(&val)被赋值给val_pin时,Rust会推导val_pin的具体类型是Pin<&i32>。i32作为基础类型默认自动实现了Unpin trait,完全符合Pin::new要求的Target: Unpin约束,因此编译通过。后续把val_pin传给f时,只是将Pin<&i32>强制转换为Pin<&dyn TestTrait>(因为i32实现了TestTrait),这个转换是合法的。
  • 第9行:直接调用f(Pin::new(&val))时,Rust会根据f的参数类型Pin<&dyn TestTrait>反向推导Pin::new(&val)的类型。它会认为你要创建的是Pin<&dyn TestTrait>,此时Pin::new的Target类型是dyn TestTrait。但dyn TestTrait本身并没有实现Unpin trait(只有当trait本身标记了Unpin,或者所有实现该trait的类型都是Unpin时,dyn Trait才会自动实现Unpin,这里TestTrait没有标记Unpin),所以违反了Pin::new的约束,触发编译错误。

简单总结:前者先创建了针对具体类型i32的Pin,再转为 trait 对象;后者试图直接创建针对 trait 对象的Pin,而 trait 对象不满足Unpin要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 00:54:11