如何将一个Vec中的Box包裹值转移到另一个Vec?
解决方案:转移Vec中的Box所有权
你当前代码的问题在于使用了v1.iter(),它生成的是共享引用,只能读取无法移动值。既然你要完全消费v1,应该用into_iter()获取每个元素的所有权,这样就能直接移动Box<B>,完全不会复制内部的B结构体。
修正后的最小示例
#[derive(Debug)] pub struct B { value: usize } fn main() { let v1: Vec<_> = (1..3).map(|i| Box::new(B{ value: i})).collect(); // 使用into_iter()获取元素所有权,直接移动Box let v2: Vec<Box<B>> = v1.into_iter().collect(); println!("{v2:?}"); }
针对实际场景:二元组Vec转三元组Vec
假设原v1是Vec<(Box<B>, usize)>,要转换为包含衍生元素的Vec<(Box<B>, usize, String)>,可以这样实现:
#[derive(Debug)] pub struct B { value: usize } fn main() { let v1: Vec<(Box<B>, usize)> = (1..3) .map(|i| (Box::new(B{ value: i }), i * 2)) .collect(); // 消费v1并转换为三元组Vec,新增衍生元素 let v2: Vec<(Box<B>, usize, String)> = v1 .into_iter() .map(|(box_b, num)| { // 生成衍生元素,这里示例基于num生成字符串 let derived = format!("derived_{num}"); (box_b, num, derived) }) .collect(); println!("{v2:?}"); }
方案说明
into_iter()会直接消耗原Vec,将每个元素的所有权转移给迭代器,因此可以自由移动Box<B>,完全不会复制其指向的B结构体,符合你避免复制大结构体的需求Box本身是轻量指针类型,移动它的开销可以忽略不计- 无需使用
Rc,因为我们直接转移所有权,不存在共享需求
你之前得到Vec<&Box<B>>的问题,就是误用了iter()(生成引用)而非into_iter()(生成所有权),后者才是消费原容器的正确选择。
内容的提问来源于stack exchange,提问作者Geoff
相关产品推荐
相关产品推荐

