Rust:如何消费结构体内部的Vec并优化实现?
你遇到的核心问题是:持有&mut Container时,无法直接调用c.vec.into_iter()——因为into_iter()需要获取Vec的所有权,但通过可变引用只能拿到&mut Vec<f32>,Rust的借用规则不允许从引用中夺走原对象的所有权。
另外你第一个例子的代码存在误区:&mut Vec<f32>调用into_iter()实际返回的是IterMut<f32>(可变引用迭代器),并不会消费Vec的元素,因此assert!(0 == vec.len())会失败,正确写法需要用到能转移所有权或清空元素的方法。
根据不同需求场景,有几种高效简洁的实现方式:
1. 消费元素所有权并保留原Vec容量(推荐)
如果需要获取元素的所有权(比如后续要对元素做转移、修改等操作),同时希望保留原Vec的内存容量(避免后续添加元素时重新分配),可以用drain(..)方法:
fn empty(c: &mut Container) { c.vec.drain(..).for_each(|x| println!("value: {:?}", x)); }
drain(..)会返回一个迭代器,拿走Vec的所有元素,同时将原Vec的长度置为0,但保留其已分配的内存容量,是效率最高的方式。
2. 消费元素所有权且不保留容量
如果不需要保留原Vec的容量,可以用std::mem::take,它会将Container中的Vec替换成一个空的默认Vec(容量为0),同时返回原Vec的所有权:
use std::mem; fn empty(c: &mut Container) { mem::take(&mut c.vec).into_iter().for_each(|x| println!("value: {:?}", x)); }
这种方式简洁直观,适合后续不需要复用原Vec容量的场景。
3. 仅读取元素并清空(不消费所有权)
如果只是需要读取元素(不需要获取所有权),同时要清空Vec,用iter()搭配clear()比直接赋值新Vec更高效:
fn empty(c: &mut Container) { c.vec.iter().for_each(|x| println!("value: {:?}", x)); c.vec.clear(); }
clear()只会将Vec的长度置为0,保留已分配的内存,比c.vec = Vec::new()更节省内存分配开销。
内容的提问来源于stack exchange,提问作者Dávid Tóth

