我有一个如下所示的函数:
fn set_many(&mut self, key_vals: impl IntoIterator<Item = (Index, T)>)
{
let (keys, vals): (Vec<_>, Vec<_>) = key_vals.into_iter().unzip();
let mut viter = vals.into_iter();
let mut iter_mut = self.many_iter_mut(keys);
while let Some(mut setter) = iter_mut.next() {
setter.set(viter.next().unwrap())
}
}
fn main() {
let mut v = SimpleVec(vec![100, 200, 300, 400, 500]);
v.set_many([(1, 20), (2, 30), (4, 50)]);
println!("modified vec: {:?}", v);
}
输出:
modified vec: SimpleVec([100, 20, 30, 400, 50])
这是可行的,但有必要调用
unzip()
来将键和值收集到单独的 Vec 中。对于大型收藏,这是不可取的。
可以更改函数签名并接受单独的 key 和 val iter 参数。不幸的是,这个函数是公共 API 的一部分并且已经在使用中,所以我不希望在下游造成不必要的破坏。
所以我想知道是否有任何方法可以重写这个函数而不需要收集?
避免
unwrap()
也很好。
这里是一个游乐场
不,这实际上不可能。可以增量压缩迭代器而不解压缩它们的原因实际上很容易理解:需要几乎无限的缓冲。
如果您有一个迭代器 I,您可以将其解压缩为两个迭代器 A 和 B,这两个迭代器必须共享对 I 的引用,因为前进 I 是获取下一个键和值的唯一方法。但是,如果您将 A 前进 100 个项目而不是 B,您仍然需要以某种方式保留从 I 的值中提取但尚未读取的 100 个 B 项目。一般来说,迭代器不会过度缓冲其内容,因为这会增加大量的内存使用量。
另一方面,只需每次调用 I 的
next
,将 A 和 B 各推进一个项目,就可以将 A 和 B 压缩到 I 中。这样效率高很多,所以就实现了。