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

两个Pin<Box<T>>内部指针能否交换?如何实现?

交换Pin<Box>内部指针的可行性与实现

问题描述

我有两个Pin<Box<T>>实例,例如通过Box::pin(struct_of_type_T)获得。Box拥有指向T类型底层值的指针,Pin确保指针指向的T类型值永远不会被移动。请问能否交换这两个“固定装箱”(Pinned-box)内部的指针?

pinned_box_1                   pinned_box_2
|-------------|                |-------------|
| pointer_one |<--交换它们--?->| pointer_two |
|-------------|                |-------------|
       |                              |
       V                              V
 struct_of_type_T_one          struct_of_type_T_two
|-------------|                |-------------|
|  value_one  |                | value_two   |
|-------------|                |-------------|
 fixed_addr                     fixed_addr

若可以,该如何实现?std::mem::swap是否适用于此场景?

解答

结论

完全可以交换,且std::mem::swap是完全适用的方案。

原因解析

Pin<Box<T>>是对Box<T>的包装类型:

  • Box<T>本身是一个指针,存储堆上T实例的地址;
  • Pin的核心约束是禁止被固定的T实例被移动,但交换Pin<Box<T>>实例时,只是交换了两个Pin内部的Box指针——堆上的T实例始终留在各自的固定内存地址,完全没有违反Pin的语义。

代码示例

use std::pin::Pin;
use std::mem;

#[derive(Debug)]
struct T {
    value: i32,
}

fn main() {
    let mut pinned_box1 = Box::pin(T { value: 10 });
    let mut pinned_box2 = Box::pin(T { value: 20 });

    println!("交换前: pinned_box1={:?}, pinned_box2={:?}", pinned_box1, pinned_box2);

    // 直接用std::mem::swap完成交换
    mem::swap(&mut pinned_box1, &mut pinned_box2);

    println!("交换后: pinned_box1={:?}, pinned_box2={:?}", pinned_box1, pinned_box2);
}

补充说明

  • 运行代码后可以看到,两个Pin<Box<T>>指向的“值”看似被交换,但本质是指针的互换,堆上的T实例从未移动位置,完全符合Pin的不变性要求;
  • 若要手动实现交换,可通过Pin::as_mut获取内部Box的可变引用后操作,但std::mem::swap已经是最简洁、安全的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:55:28