我有一个如下所示的函数:

    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中.对于大型集合,这是不可取的.

更改函数签名并接受单独的密钥和Val ITER参数是可行的.不幸的是,该函数是公共API的一部分,并且已经在使用中,所以我不希望在下游造成不必要的 destruct .

所以我想知道有没有什么方法可以重写这个函数而不收集?

避免unwrap()美元也是一件好事.

这是一张playground美元的钞票

推荐答案

不,这不太可能.可以递增地压缩迭代器而不解压它们的原因实际上很容易理解:需要几乎无限的缓冲.

如果您有一个迭代器i,您可以将其解压缩到两个迭代器A和B中,这两个迭代器必须共享对i的引用,因为前进i是获取下一个键和值的唯一方法.然而,如果您将A前进100项而不是B,您仍然必须以某种方式保持从I的值中提取但尚未读取的那100个B项.一般而言,迭代器不会缓冲超出必要的内容,因为这可能会增加大量的内存使用.

另一方面,通过简单地将A和B分别前移一项到I‘s next,就可以将A和B压缩到I中.这要高效得多,所以它得到了实施.

Rust相关问答推荐

如果A == B,则将Rc A下推到Rc B

如何将`Join_all``Vec<;Result<;Vec<;Foo&>;,Anywhere::Error&>;`合并到`Result<;Vec<;Foo&>;,Anywhere::Error&>;`

有没有更好的方法从HashMap的条目初始化 struct ?

MutexGuard中的过滤载体不需要克隆

用 rust 蚀中的future 展望 struct 的future

有没有可能让泛型Rust T总是堆分配的?

失真图像图形捕获Api

为什么实现特征的对象期望比具体对象有更长的生命周期?

try 实现线程安全的缓存

Rust 如何将链表推到前面?

go 重并堆积MPSC通道消息

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

Rust 引用元组和引用元组

如何创建递归borrow 其父/创建者的 struct ?

If let expression within .iter().any

Cargo:如何将整个目录或文件包含在功能标志中?

如何从 many0 传播 Nom 失败上下文?

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?

为什么当borrow 变量发生变化时,borrow 变量不会改变?

为什么 Rust 中的关联类型需要明确的生命周期注释?