如何在循环中将变量更新为对在循环中创建的值的引用? [英] How do I update a variable in a loop to a reference to a value created inside the loop?

查看:55
本文介绍了如何在循环中将变量更新为对在循环中创建的值的引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想输入一个由函数借用的变量n的循环.在每个步骤中,n取一个新值;退出循环时,将在其他变量的帮助下完成该工作,并且n将不再使用 .

I want to enter a loop with a variable n which is borrowed by the function. At each step, n takes a new value; when exiting the loop, the job is done, with the help of other variables, and n will never be used again.

如果我不使用引用,那么我会遇到这样的事情:

If I don't use references, I have something like this:

fn test(n: Thing) -> usize {
    // stuff
    let mut n = n;
    for i in 1..10 {
        let (q, m) = n.do_something(...);
        n = m;
        // stuff with x
    }
    x
}

x是使用qm进行某些计算的结果,但是它是usize类型,在这部分代码中我没有遇到任何问题.我没有测试此代码,但这是个主意.我可以编写像这样的代码.

x is the result of some computation with q and m but it is an usize type and I didn't encounter any issue in this part of the code. I didn't test this code, but this is the idea. I could make code written like this work.

因为我想参考一下;我试图写:

Since I want to do it with a reference; I tried to write:

fn test(n: &Thing) -> usize {
    // stuff
    let mut n = n;
    for i in 1..10 {
        let (q, m) = (*n).do_something(...);
        n = &m;
        // stuff with x
    }
    x
}

现在,由于m的生存期短于n,因此无法编译代码.我试图通过做一些棘手的事情或克隆事情来使其工作,但这不是正确的方法.在C语言中,代码之所以有效,是因为我们不在乎退出循环时n指向什么,因为在循环后不使用n.我完全理解,这就是Rust和C的不同之处,但是我很确定在Rust中存在一种干净的方法.

Now the code will not compile because m has a shorter lifetime than n. I tried to make it work by doing some tricky things or by cloning things, but this can't be the right way. In C, the code would work because we don't care about what n is pointing to when exiting the loop since n isn't used after the loop. I perfectly understand that this is where Rust and C differ, but I am pretty sure a clean way of doing it in Rust exists.

将我的问题考虑得很笼统;我不是在寻求针对特定问题的临时解决方案.

Consider my question as very general; I am not asking for some ad-hoc solution for a specific problem.

推荐答案

正如 Chris Emerson指出的那样,这样做是不安全的,也不可能用C语言编写类似的代码.您要引用的变量在每次循环迭代结束时超出范围,因此在下一次迭代的开始时您将具有 dangling指针.这将导致Rust试图防止的所有内存错误; 铁锈阻止您做一些您认为安全的不良事情.

As Chris Emerson points out, what you are doing is unsafe and it is probably not appropriate to write code like that in C either. The variable you are taking a reference to goes out of scope at the end of each loop iteration, and thus you would have a dangling pointer at the beginning of the next iteration. This would lead to all of the memory errors that Rust attempts to prevent; Rust has prevented you from doing something bad that you thought was safe.

如果您想要可以借用或拥有的东西;这是 Cow :

If you want something that can be either borrowed or owned; that's a Cow:

use std::borrow::Cow;

#[derive(Clone)]
struct Thing;

impl Thing {
    fn do_something(&self) -> (usize, Thing) {
        (1, Thing)
    }
}

fn test(n: &Thing) -> usize {
    let mut n = Cow::Borrowed(n);
    let mut x = 0;

    for _ in 1..10 {
        let (q, m) = n.do_something();
        n = Cow::Owned(m);
        x = x + q;
    }

    x
}

fn main() {
    println!("{}", test(&Thing));
}

这篇关于如何在循环中将变量更新为对在循环中创建的值的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆