我正在研究迭代器的笛卡尔幂实现。我遇到了一个障碍,我似乎无法存储我传递的迭代器的可查看副本的向量。无论我如何摆弄盒子和指针,它都不起作用,因为 Vec<Peekable<dyn Iterator<Item = T>>>
编译时没有已知的大小。
关于如何在编译时知道这个大小有什么想法吗?我真的只需要存储一个指向向量的指针,对吗?没有理由不能在堆上创建它,不是吗?
这是我到目前为止所拥有的(忽略 next() 实现,这只是为了测试我是否可以存储迭代器并正确使用它的下一个函数):
mod cartesian_power {
use core::iter::Peekable;
pub struct CartesianPower<T> {
prototype: Box<dyn Iterator<Item = T>>,
iters: Vec<Peekable<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 iters = Vec::with_capacity(power);
for _ in 0..power {
iters.push(vals.clone().into_iter().peekable());
}
Self {
prototype: Box::new(vals.into_iter()),
iters: iters,
}
}
}
impl<T> Iterator for CartesianPower<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.prototype.next()
}
}
}
最佳答案
您无法存储 Vec<dyn Trait>
(或 Vec<Peekable<dyn Trait>>
)直接,您必须使用间接寻址,因为每个元素可以具有不同的大小: Vec<Box<Peekable<dyn Iterator<Item = T>>>>
.
但是,由于您的情况中的所有迭代器都是相同的,因此您可以使用泛型并避免 Box
的性能影响和动态调度:
pub struct CartesianPower<I: Iterator> {
prototype: I,
iters: Vec<Peekable<I>>,
}
impl<Iter: Iterator> CartesianPower<Iter> {
pub fn new<I>(vals: I, power: usize) -> CartesianPower<Iter>
where
I: IntoIterator<IntoIter = Iter>,
I: Clone,
<I as IntoIterator>::IntoIter: 'static,
{
let mut iters = Vec::with_capacity(power);
for _ in 0..power {
iters.push(vals.clone().into_iter().peekable());
}
Self {
prototype: vals.into_iter(),
iters: iters,
}
}
}
impl<I: Iterator> Iterator for CartesianPower<I> {
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
self.prototype.next()
}
}
关于rust - 如何解析 'Vec<Peekable<dyn Iterator<Item = T>>> doesn' t 的大小在编译时已知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73822562/