首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >for循环如何实现into_iter

for循环如何实现into_iter
EN

Stack Overflow用户
提问于 2022-05-16 12:04:04
回答 2查看 156关注 0票数 3

跟进这个问题,它被标记为重复的问题这里

如何循环实现into_iter的概念一直困扰着我,这个回答给我带来了更多的问题,比如重借的条款,除了一个地方之外,在生锈的正式文档中根本没有提到这个问题。

据我对这个评论的理解,当vec是一个可变的引用时,for i in vec.into_iter()实际上是场景后面的for i in (&mut *vec).into_iter()

那么for i in vec呢,它实际上是i in vec.into_iter()吗?关于for循环是如何实现的,如何触发重新借款以及它是如何工作的,有什么地方有更详细的地方吗?

供参考的代码:

代码语言:javascript
复制
fn question1_1(vec: &mut [i32]) {
    for &mut item in vec.into_iter() {
        println!("{}", item);
    }
    for &mut item in vec { // --- `vec` moved due to this implicit call to `.into_iter()`
        println!("{}", item);
    }
    vec; // Error: move occurs because `vec` has type `&mut [i32]`, which does not implement the `Copy` trait
}

pub fn main() {
    let mut s = vec![1, 2, 3];
    question1_1(&mut s);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-16 12:27:28

for循环被设计成(通过检查HIR可以看到):

代码语言:javascript
复制
{
    let _t = match IntoIterator::into_iter(iter) {
        mut iter => loop {
            match Iterator::next(&mut iter) {
                None => break,
                Some(i) => {
                    // Body
                }
            }
        },
    };
    _t
}

特别地,通过执行IntoIterator::into_iter(iterable)将可迭代转换为迭代器。每个特征,包括IntoIterator,都有一个隐藏的Self泛型参数,因此这实际上是IntoIterator::<_>::into_iter(iterable)。通过重新借用POV,这类似于:

代码语言:javascript
复制
fn foo<T>(v: T) {}

foo::<_>(iterable)

确切的细节在可变引用有移动语义吗?中得到了解释,但总体思路是,它没有文档化。当前的工作方式是这样的,当编译器无法在没有推论的情况下确定某物是可变的引用时,它就不会被重新借用。因为_需要推理,所以不能再借用它。

接收方的工作方式不同(总是重新借用),因此iterable.into_iter()确实执行重借。事实上,这种行为与自动裁剪有关,而不是重新借款。另见铁锈的自动解除规则是什么?

票数 1
EN

Stack Overflow用户

发布于 2022-05-16 13:29:41

除了在操场上使用HIR来检查如何在场景后面运行for循环之外,这里是关于for循环是如何去糖化的官方文档。

从文档给出的示例中,值( vec类型)被传递到IntoIterator::into_iter() IntoIterator::into_iter(values)中,这与作为方法values.into_iter()调用不同。

代码语言:javascript
复制
let values = vec![1, 2, 3, 4, 5];

for x in values {
    println!("{}", x);
}

脱糖

代码语言:javascript
复制
let values = vec![1, 2, 3, 4, 5];
{
    let result = match IntoIterator::into_iter(values) {
        mut iter => loop {
            let next;
            match iter.next() {
                Some(val) => next = val,
                None => break,
            };
            let x = next;
            let () = { println!("{}", x); };
        },
    };
    result
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72258925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档