为什么File需要是可变的来调用Read :: read_to_string?

Jam*_*Lay 7 file immutability rust

这是第二版Rust教程中的一行:

let mut f = File::open(filename).expect("file not found");
Run Code Online (Sandbox Code Playgroud)

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

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

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
Run Code Online (Sandbox Code Playgroud)

整个来源:

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);
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 7

我假设它是因为该方法read_to_string将实例作为self参数作为可变参数

对,那是正确的:

fn read_to_string(&mut self, buf: &mut String) -> Result<usize>
Run Code Online (Sandbox Code Playgroud)

特征方法Read::read_to_string将接收器作为可变参考,因为通常,这是从某些东西实现"读取"所需要的.你要改变一个缓冲器或偏移或东西.

是的,实际File 可能只包含底层文件描述符(例如在Linux或macOS上)或句柄(例如Windows).在这些情况下,操作系统处理跨线程同步访问.这甚至都没有保证 - 这取决于平台.像Redox这样的东西实际上可能在其实现中有一个可变引用File.

如果Read特征不接受a &mut self,则类似的类型BufReader必须使用内部可变性之类的东西,从而降低Rust引用的有用性.

也可以看看:

  • @AustinHeller 在工作案例中,您创建一个对“File”的临时不可变引用,然后隐式地采用对临时的可变引用,生成一个“&amp;mut &amp;File”。 (2认同)