如何解决‘Vec<Peekable<dyn Iterator<Item = T>>>编译期大小未知’问题?
解决
Vec<Peekable<dyn Iterator<Item = T>>>编译期大小不确定的问题 问题核心在于Peekable<dyn Iterator<Item=T>>是动态大小类型(DST):dyn Iterator本身是不定长的 trait 对象,而Peekable的结构体大小完全依赖内部迭代器的大小,因此整个Peekable<dyn Iterator<...>>无法在编译期确定大小。而Vec要求元素必须是编译期大小固定的类型(满足Sized约束),直接使用就会编译失败。
最直接的解决方式是让Peekable包裹装箱后的迭代器,也就是Peekable<Box<dyn Iterator<Item=T>>>——Box<dyn Iterator>是大小固定的指针类型,因此Peekable包裹它后整个类型就变成了Sized,可以正常存入Vec。
修改后的完整代码
mod cartesian_power { use core::iter::Peekable; pub struct CartesianPower<T> { prototype: Box<dyn Iterator<Item = T>>, // 将 Peekable 的内部迭代器装箱,确保整个类型大小确定 iters: Vec<Peekable<Box<dyn Iterator<Item = T>>>>, } impl<T> CartesianPower<T> { pub fn new<I>(vals: I, power: usize) -> CartesianPower<T> where I: IntoIterator<Item = T>, I: Clone, <I as IntoIterator>::IntoIter: 'static, { let mut iters = Vec::with_capacity(power); for _ in 0..power { // 先将迭代器装箱,再传入 Peekable let iter = Box::new(vals.clone().into_iter()); iters.push(Peekable::new(iter)); } Self { prototype: Box::new(vals.into_iter()), iters, } } } impl<T> Iterator for CartesianPower<T> { type Item = T; fn next(&mut self) -> Option<T> { self.prototype.next() } } }
关键改动说明
- 结构体字段类型调整:将
iters的类型从Vec<Peekable<dyn Iterator<Item = T>>>改为Vec<Peekable<Box<dyn Iterator<Item = T>>>>,通过Box将动态大小的迭代器转为固定大小的指针,满足Vec对元素的Sized要求。 - 迭代器装箱逻辑:在创建
Peekable实例时,先将vals.clone().into_iter()的结果用Box::new装箱,再传给Peekable::new完成包装。
你提到的“存储向量指针”思路不可行——比如Box<Vec<Peekable<dyn Iterator<Item=T>>>>只是把整个Vec放到堆上,但并没有解决Peekable<dyn Iterator>本身是DST的问题,依然会编译失败。只有让Vec的元素本身是Sized类型,才是正确的解决路径。
内容的提问来源于stack exchange,提问作者Justin Huffman
相关产品推荐
相关产品推荐

