为什么可以在对 File 的不可变引用上实现 Read?

Why is it possible to implement Read on an immutable reference to File?

如果您查看 docs for Read,大多数方法都接受 &mut self。这是有道理的,因为读取某物通常会更新内部偏移量,因此下一次读取 returns 不同的数据。然而,这编译:

use std::io::Read;
use std::fs::File;

fn main() {
    let file = File::open("/etc/hosts").unwrap();
    let vec = &mut Vec::new();
    (&file).read_to_end(vec).unwrap();
    println!("{:?}", vec);
}

该文件不可变,但肯定正在读入数据。这对我来说似乎不正确。 ,但一个不可变实例看似正在发生变异这一事实似乎仍然很奇怪。

正如@kennytm 指出的那样,a.read_to_end(vec) 等同于 Read::read_to_end(&mut a, vec),因此 (&file).read_to_end(vec) 扩展为 Read::read_to_end(&mut &file, vec)。在后一个表达式中,&file 是类型 &File 的新临时值。使用 mutable 对表达式的引用没有问题(例如 &mut 42)。这正是这里发生的事情。表达式是对 immutable 值的引用这一事实并不重要,因为我们实际上无法通过 &mut &T.

来改变该值

关于为什么我们不需要 File 为 mutable 的问题:File 基本上只是一个新类型的文件描述符,即打开文件的索引table 即由 OS 管理。 read 和朋友根本不会改变这个描述符,这就是 File 不需要突变的原因。当然会发生变异,但这是由操作系统在其自己的数据结构上完成的,而不是在您的用户态 rust 代码中完成的。