两个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
相关产品推荐
相关产品推荐

