如何将不可变切片传递给需要 &mut impl 读取的 fn?



我有一个fn看起来像这样:

use std::io::Read;
fn read_something(file: &mut impl Read) {
let _ = file.read(&mut [0; 8]);
}

当我像这样传递一个Vec的切片时:

fn main() {
let vector = vec![1, 2, 3, 4];
read_something(&mut &vector[..]);
}

可以正常工作。但是,当我首先将切片保存到一个变量中时,它不会编译:

fn main() {
let vector = vec![1, 2, 3, 4];
let slice = &vector[..];
read_something(&mut slice);
}

编译器告诉我

不能借用为可变

游乐场

这两种情况有什么不同?为什么第一个例子工作,即使vector不声明为可变的吗?我怎么能把&[u8]片传给吃&mut impl Readfn片呢?

我如何将&[u8]切片传递到fn中,它会吃掉&mut impl Read?

mut添加到保存切片的变量中:

let vector = vec![1, 2, 3, 4];
let mut slice = &vector[..];
read_something(&mut slice);

注意,这使得切片可变,这意味着它可以被修改以引用不同的数据(read_something()使用)。它不允许切片改变不可变向量。

这两种情况有什么不同?为什么第一个例子工作,即使矢量没有声明为可变的吗?

在第一种情况下,vector是不可变的,但是保存切片的未命名临时对象是。你的第一个例子是这样的:

let vector = vec![1, 2, 3, 4]; // immutable Vec
let mut tmp = &vector[..]; // mutable slice referring to immutable Vec
read_something(&mut tmp);
// here `tmp` may be pointing to different content
// (e.g. a subset of the vector, or something static)

vector不需要是可变的,因为Read::read()&[u8]的impl不试图修改slice的内容,它只修改slice本身(概念上是一个<指针,length>元组)。它可以这样做,因为Read是为&[u8]实现的,所以当<&[u8] as Read>::read()接收到&mut self时,它的完整类型是&mut &[u8]——一个对某些不可变数据片的可变引用。

Read::read()对于&[u8]所做的是将接收到的片替换为包含片中尚未读取部分的更小的片。(这允许"相同的";片传递给read(),最终耗尽所有数据。)由于您读取到的8字节缓冲区大于作为读取源的4字节片,因此在read_something()返回(playground)后,修改后的tmp片将为空。

最新更新