为什么文件需要可变才能调用 Read::read_to_string?

Why does a File need to be mutable to call Read::read_to_string?

这是来自 2nd edition Rust tutorial 的一行:

let mut f = File::open(filename).expect("file not found");

我假设文件描述符是一个基本不变且只读的数字的包装器。

编译器抱怨不能可变地借用文件,我假设这是因为方法 read_to_string 将实例作为 self 参数作为可变的,但问题是 "why"?文件描述符会发生什么变化?它是在跟踪光标位置还是什么?

error[E0596]: cannot borrow immutable local variable `fdesc` as mutable
  --> main.rs:13:5
   |
11 |     let fdesc = File::open(fname).expect("file not found");
   |         ----- consider changing this to `mut fdesc`
12 |     let mut fdata = String::new();
13 |     fdesc.read_to_string(&mut fdata)
   |     ^^^^^ cannot borrow mutably

整个来源:

fn main() {
    let args: Vec<String> = env::args().collect();
    let query = &args[1];
    let fname = &args[2];
    println!("Searching for '{}' in file '{}'...", query, fname);

    let fdesc = File::open(fname).expect("file not found"); //not mut
    let mut fdata = String::new();
    fdesc.read_to_string(&mut fdata)
        .expect("something went wrong reading the file");

    println!("Found: \n{}", fdata);
}

I'm assuming it's because the method read_to_string takes the instance as the self argument as mutable

是的,没错:

fn read_to_string(&mut self, buf: &mut String) -> Result<usize>

trait 方法 Read::read_to_string 将接收者作为可变引用,因为一般来说,这是从某物实现 "reading" 所需要的。您将要更改缓冲区或偏移量或 某事

是的,一个实际的 File 可能 只包含一个底层文件描述符(例如在 Linux 或 macOS 上)或一个句柄(例如 Windows).在这些情况下,操作系统负责同步跨线程访问。但这甚至不能保证——这取决于平台。像 Redox 这样的东西在 File.

的实现中实际上可能有一个可变引用

如果 Read 特征不接受 &mut self,那么像 BufReader 这样的类型将不得不使用内部可变性之类的东西,从而降低 Rust 引用的有用性。

另请参阅: