如果您查看docs for Read
,则大多数方法都会接受&mut self
。这是有道理的,因为从某物读取通常会更新内部偏移量,因此下一次读取将返回不同的数据。但是,这会编译:
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);
}
该文件不可变,但数据肯定被读入。这对我来说似乎不对。 It was pointed out that there is an impl<'a> Read for &'a File
,但不可变实例似乎正在变异的事实似乎仍然很奇怪。
答案 0 :(得分:9)
正如@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
类型的新临时值。对表达式进行可变引用没有问题(例如&mut 42
)。这正是这里发生的事情。表达式是对不可变值的引用这一事实无关紧要,因为我们实际上无法通过&mut &T
来改变该值。
关于为什么我们不需要File
是可变的问题:File
基本上只是一个新形式的文件描述符,即由OS管理的开放文件表的索引。 read
和朋友根本不会改变这个描述符,这就是File
不需要变异的原因。当然存在突变,但这是由操作系统在其自己的数据结构上完成的,而不是在用户土地生锈代码中。