在Rust的 for循环中,IntoIterator::into_iter(values) 与values.into_iter() 的区别

编程语言 2026-07-09

在阅读for-loops-and-IntoIterator时,我理解了Rust如何把for循环展开成IntoIterator的遍历;到目前为止,一切都挺好。

我开始玩了一下,决定把 &mut 当作值来使用,结果看到如下

    let values = &mut vec![1., 2., 3., 4., 5.];
    {
        let result = match IntoIterator::into_iter(values) { // values moved here
            mut iter => loop {
                let next;
                match iter.next() {
                    Some(val) => next = val,
                    None => break,
                };
                let x = next;
                let () = {
                    println!("{x}");
                };
            },
        };
        result
    }
    println!("{values:?}"); // BOOM: borrow of moved value


    let values = &mut vec![1., 2., 3., 4., 5.];
    // let mut values = vec![1., 2., 3., 4., 5.];
    {
        let result = match values.into_iter() { // Why aren't values moved?
            mut iter => loop {
                let next;
                match iter.next() {
                    Some(val) => next = val,
                    None => break,
                };
                let x = next;
                let () = {
                    println!("{x}");
                };
            },
        };
        result
    }
    println!("{values:?}");  // Surprise (to me): Compiler says this is ok, shouldn't `values.into_iter()` have moved values?

难道 values.into_iter() 不等价于 IntoIterator::into_iter(values) 吗?请参见 playground.

后来我在某处看到,用点调用的方法确实会进行重新借用,但用完全限定名调用时不会发生重新借用,这样对吗?

如果我的理解没错,这在文档的哪里有解释?

解决方案

后来我在某处看到,用点调用的方法确实会进行重新借用,但用完全限定名调用时不会发生重新借用,对吗?

差不多。使用路径语法调用一个方法仍然会发生重新借用,前提是目标类型事先被确认为引用类型。但 IntoIterator::into_iter() 是一个trait方法——对 Self 泛型,因此它不会。用例如 <&mut _ as IntoIterator>::into_iter(values) 调用就可以。

如果我的理解没错,这在文档的哪里有解释?我还没找到

不幸的是,关于重新借用的文档讲解得还不够充分。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章