为什么只有在声明在循环外时才会发生这种不变性错误? [英] Why does this immutability error only happens if declaration is outside the loop?

查看:52
本文介绍了为什么只有在声明在循环外时才会发生这种不变性错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用我从文件中获取的一些数据填充缓冲区,然后从该缓冲区读取以处理该数据.所有这一切都在循环中反复进行.

I am trying to fill a buffer with some data I get from a file, and then read from that buffer to do stuff with that data. All of that iteratively, inside a loop.

如果我这样做,它会完美编译:

If I do this, it compiles perfectly:

use std::fs::File;
use std::io::{BufReader, IoSliceMut, Read};

fn do_something(buffer_0: &[u8; 8], buffer_1: &[u8; 2]) {
    // Do something
}

fn main() {
    let file = File::open("/path/to/file").expect("Error opening file");

    let mut reader = BufReader::new(file);
    let buffer_0 = &mut [0; 8];
    let buffer_1 = &mut [0; 2];

    loop {
        let buffer = &mut [IoSliceMut::new(buffer_0), IoSliceMut::new(buffer_1)];
        reader
            .read_vectored(buffer)
            .expect("Error reading from file");
        do_something(buffer_0, buffer_1);
    }
}

现在,如果我在循环之外声明 buffer,就像这样:

Now, if I declare buffer outside of the loop, like this:

use std::fs::File;
use std::io::{BufReader, IoSliceMut, Read};

fn do_something(buffer_0: &[u8; 8], buffer_1: &[u8; 2]) {
    // Do something
}

fn main() {
    let file = File::open("/path/to/file").expect("Error opening file");

    let mut reader = BufReader::new(file);
    let buffer_0 = &mut [0; 8];
    let buffer_1 = &mut [0; 2];

    let buffer = &mut [IoSliceMut::new(buffer_0), IoSliceMut::new(buffer_1)];

    loop {
        reader
            .read_vectored(buffer)
            .expect("Error reading from file");
        do_something(buffer_0, buffer_1);
    }
}

出现如下编译错误:

error[E0502]: cannot borrow `*buffer_0` as immutable because it is also borrowed as mutable
  --> src/main.rs:21:22
   |
15 |     let buffer = &mut [IoSliceMut::new(buffer_0), IoSliceMut::new(buffer_1)];
   |                                        -------- mutable borrow occurs here
...
19 |             .read_vectored(buffer)
   |                            ------ mutable borrow later used here
20 |             .expect("Error reading from file");
21 |         do_something(buffer_0, buffer_1);
   |                      ^^^^^^^^ immutable borrow occurs here

buffer_1 当然也一样.

我不明白为什么这段代码在循环中被认为是不安全的.另外,是否可以在不移动 buffer 声明的情况下使其安全?

I don't understand why this code is considered unsafe inside the loop. Also, is it possible to make it safe without moving the buffer declaration?

非常感谢 Rust 大师的智慧 :)

Rust gurus wisdom is much appreciated :)

推荐答案

在第一个示例中,buffer 的每个实例仅持续循环的一次迭代.由于非词法生命周期,编译器可以计算出您在调用 read_vectored 后不会重用 IoSliceMut 的那些实例,因此它们持有的可变借用是发布,代码编译.

In the first example, each instance of buffer lasts only for one iteration of the loop. Due to non-lexical lifetimes, the compiler can work out that you don't reuse those instances of IoSliceMut after your call to read_vectored, so the mutable borrows that they hold are released, and the code compiles.

在您的第二个示例中,您明确表示应该为整个循环保留 IoSliceMut 的这两个实例,并且它们应该用于每次调用read_vectored - 因此他们的可变借用不可能在最后一次迭代之前被释放.

In your second example, you're explicitly saying that those two instances of IoSliceMut should be kept for the entire loop, and they should be used for every call to read_vectored - therefore their mutable borrows cannot not possibly be released until the very last iteration.

这篇关于为什么只有在声明在循环外时才会发生这种不变性错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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