如果你查看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,但一个不可变的实例似乎正在发生变异这一事实似乎仍然很奇怪.

推荐答案

正如@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)进行可变引用没有问题.这里发生的就是这样.表达式是对不可变值的引用这一事实并不重要,因为我们实际上无法通过一个变量来改变该值.

关于为什么我们不需要File是可变的这个问题:File基本上只是一个新类型的文件描述符,即一个由操作系统管理的开放文件表的索引.read和朋友们根本不会改变这个描述,这就是为什么File不需要变异.当然会发生变异,但这是由操作系统在其自身的数据 struct 上完成的,而不是在用户代码中完成的.

Rust相关问答推荐

通用池类型xsx

如何将元素添加到向量并返回对该元素的引用?

无法理解铁 rust &S错误处理

无法从流中读取Redis请求

Gtk4-rs:将监视器作为gdk::monitor获取,而不是作为glib::对象获取

如何在Rust中缩短数组

在什么情况下 `..._or()` 比 `..._or_else(|| {})` 更好,为什么?

为什么是&mut发送?线程如何在安全的 Rust 中捕获 &mut?

`tokio::pin` 如何改变变量的类型?

我可以在 Rust 中 serde struct camel_case 和 deserde PascalCase

是否可以通过可变引用推进可变切片?

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

Some(v) 和 Some(&v) 有什么区别?

内部值发生变化时 Rc 的行为

哪些特征通过 `Deref` 而哪些不通过?

为什么可以在迭代器引用上调用 into_iter?

为什么传递 option.as_ref 的行为不同于使用匹配块并将内部映射到 ref 自己?

Rust 中 `Option` 的内存开销不是常量

如何在 Rust 中编写涉及异步的重试函数

如何将 while 循环内的用户输入添加到 Rust 中的向量?