Rust 如何初始化数组并保存对其项的引用?

Rust 如何初始化数组并保存对其项的引用?,rust,borrow-checker,ownership,borrowing,Rust,Borrow Checker,Ownership,Borrowing,() 我知道编译器正在拯救我自己,但我真的想要这种行为,我不想用safe强制它通过,因为我肯定会搞砸的。我有什么选择 我有一种感觉,它与我尚未理解的生命有关。也许是因为同一数据有两个所有者?我不认为这是一个问题,只要你活得比v 我怎样才能从中恢复过来?或者是因为有多个所有者,所以我需要重新考虑我的方法,所以这是完全不允许的 我遇到了这个麻烦,因为我需要复制一个只能克隆的类型,但我还得问另一个问题。迭代器来拯救你 由于编译器无法对循环中的代码进行推理,因此需要以类型系统和生存期要求的形式对其进行限

()

我知道编译器正在拯救我自己,但我真的想要这种行为,我不想用
safe
强制它通过,因为我肯定会搞砸的。我有什么选择

我有一种感觉,它与我尚未理解的生命有关。也许是因为同一数据有两个所有者?我不认为这是一个问题,只要你活得比v

我怎样才能从中恢复过来?或者是因为有多个所有者,所以我需要重新考虑我的方法,所以这是完全不允许的


我遇到了这个麻烦,因为我需要复制一个只能克隆的类型,但我还得问另一个问题。

迭代器来拯救你

由于编译器无法对循环中的代码进行推理,因此需要以类型系统和生存期要求的形式对其进行限制。这是通过迭代器实现的:

error[E0506]: cannot assign to `u[_]` because it is borrowed
 --> src/lib.rs:5:9
  |
5 |         u[i] = i;
  |         ^^^^^^^^ assignment to borrowed `u[_]` occurs here
6 |         let e = &(u[i]);
  |                 ------- borrow of `u[_]` occurs here
7 |         v.push(e);
  |         - borrow later used here
让mut u:[usize;3]=[0;3];
让mut v:Vec=Vec![];
U
.iter_mut()
.enumerate()
.对于每个(|(idx,val)|{
*val=idx;
v、 推送(&*val);
});

根据要求;这就是它的作用:

  • u.iter_mut()
    源于一个事实,即,和片具有一个函数。此迭代器生成一个
    &mut T

  • .enumerate()
    接受一个迭代器,并在索引上加上一个标记。迭代器项的转换如下:
    T
    转到
    (usize,T)

  • .for_each(f)
    完全清空迭代器并为每个元素运行函数(
    f
    是函数)<在这种情况下,code>f必须具有调用签名
    fn(值:(usize,&mut T))->()

  • 我们将闭包传递给每个调用的
    ,这很重要:闭包可以可变地捕获
    v
    。这允许修改
    v
    ,因此我们可以在闭包中说
    v.push

至于为什么这样做有效,而你的却没有:

  • 你有一个简单的for循环。for循环可以做任何事情,而编译器不会投入精力来验证您正在做的事情。根据编译器的说法,它只会确保你所做的事情不是非法的,并且会对此保持保守

  • 另一方面,它使用闭包的语义来保证除了通过当前看到的元素之外,不能以任何其他方式修改
    u
    。编译器认为对
    u
    的每个元素的引用都是唯一的,因为对
    u
    的原始引用是唯一的,因此它对此没有问题。然后,
    v
    中借用(或引用,相同术语)的寿命与
    u
    的寿命相同,因此得出结论,
    v
    以优雅的方式借用了
    u

  • 这在循环中并不容易,因为编译器实际上必须逐行跟踪代码调用,以确定这一点。这将是一个泡菜。这是一个棘手的问题,所以它只是向你吐露了一个错误,因为在更复杂的情况下证明它太难了


您可以将循环拆分为两个过程。 初始化条目,然后引用它们:

let mut u: [usize; 3] = [0; 3];
let mut v: Vec<&usize> = vec![];
u
    .iter_mut()
    .enumerate()
    .for_each(|(idx, val)| {
        *val = idx;
        v.push(&*val);
    });
这是因为在初始化循环完成后,不再需要对u的可变引用

我有一种感觉,它与我尚未理解的生命有关。也许是因为同一数据有两个所有者?我不认为这是一个问题,只要你活得比v


u和v的寿命不是问题,问题在于将引用引入可变结构。

在大多数情况下,我更喜欢这种方法;但在我的特殊情况下,我需要赋值和推引用同时发生。你的解释很有帮助!
let mut u: [usize; 3] = [0; 3];
let mut v: Vec<&usize> = vec![];
u
    .iter_mut()
    .enumerate()
    .for_each(|(idx, val)| {
        *val = idx;
        v.push(&*val);
    });
    let mut u:[usize;3] = [0;3];
    let mut v = vec![];

    for i in 0..3 {
        u[i] = i;
    }

    for i in 0..3 {
        let e = &(u[i]);
        v.push(e);
    }