Rust 无法为闭包中使用的变量赋值,因为它是借用的

Rust 无法为闭包中使用的变量赋值,因为它是借用的,rust,closures,Rust,Closures,我试图通过使用小的helper闭包使代码的某些部分更易于阅读 fn main() { let mut loop_index = 0; let get_src_index = || return loop_index % 2; let get_dst_index = || return (loop_index + 1) % 2; loop_index += 1; } 还有一些闭包使用了get_src_index()和get_dst_index(),但它们对问题

我试图通过使用小的helper闭包使代码的某些部分更易于阅读

fn main() {
    let mut loop_index = 0;

    let get_src_index = || return loop_index % 2;
    let get_dst_index = || return (loop_index + 1) % 2;

    loop_index += 1;
}
还有一些闭包使用了
get_src_index()
get_dst_index()
,但它们对问题并不重要。问题是我不能再修改
循环索引了:

error[E0506]:无法分配给'loop\u index',因为它是借用的
-->src/main.rs:6:5
|
4 |让get_src_index=| |返回循环_index%2;
|--此处出现'loop_index'的借用
5 |让get|dst|u index=| | return(loop|u index+1)%2;
6 |回路指数+=1;
|^^^^^^^^^^^^^^^^^^^^对借用的“循环”索引的赋值发生在此处

我不太明白为什么Rust不允许增加
loop\u index
变量。是否有一种更“生疏”的方法来执行此操作?

正如错误消息所述,您无法更改该值,因为它是借用的。就像你说的一样:

let mut loop_index = 0;
let foo = &loop_index;
loop_index += 1;
不允许你这么做。这是防锈的一个基本概念,也是其安全性的基础

为什么闭包有对变量的引用?这就是闭包到的全部要点。闭包根据内部发生的操作推断如何捕获变量,在这种情况下,引用就足够了

这通常是您想要的,因为引用很容易传递。在这种情况下,您有数字,因此没有理由选择引用。我们可以使用
move
关键字将数字移动到闭包中。由于数字实现了
复制
,这将生成一个副本。然后,闭包与现有值完全分离:

let mut loop_index = 0;

let get_src_index = move || loop_index % 2; // No need for `return`
let get_dst_index = move || (loop_index + 1) % 2;

loop_index += 1;
然而,我不认为这些特殊的闭包真的能给你带来什么。整数运算通常比较便宜,而条件运算通常不那么便宜,因此进行额外的计算可能会更好


如果您需要修改
循环索引
并在闭包中反映该更改,则可以使用
单元格

use std::cell::Cell;

fn main() {
    let mut loop_index = Cell::new(0);

    let get_src_index = || loop_index.get() % 2;
    let get_dst_index = || (loop_index.get() + 1) % 2;

    loop_index.set(loop_index.get() + 1);
}


更好的是,在许多情况下,您不需要维护自己的循环索引。为您处理。

编译器的消息似乎与上面的代码不匹配。请制作一个MCVE,最好有一个链接到@E_net4,这也吸引了我。OP将代码分为两个块,但这两个块的组合产生了错误。感谢您的解释。我不认为我可以在这里使用
enumerate()
,但是使用
单元格
效果很好!:)