为什么这段代码不编译:

fn use_cursor(cursor: &mut io::Cursor<&mut Vec<u8>>) {
    // do some work
}

fn take_reference(data: &mut Vec<u8>) {
    {
        let mut buf = io::Cursor::new(data);

        use_cursor(&mut buf);
    }

    data.len();
}

fn produce_data() {
    let mut data = Vec::new();
    take_reference(&mut data);
    data.len();
}

这种情况下的错误是:

error[E0382]: use of moved value: `*data`
  --> src/main.rs:14:5
   |
9  |         let mut buf = io::Cursor::new(data);
   |                                       ---- value moved here
...
14 |     data.len();
   |     ^^^^ value used here after move
   |
   = note: move occurs because `data` has type `&mut std::vec::Vec<u8>`, which does not implement the `Copy` trait

io::Cursor::new的签名意味着它拥有自己的论点.在本例中,参数是对Vec的可变引用.

pub fn new(inner: T) -> Cursor<T>

这对我来说有点道理;因为Cursor::new拥有其参数(而不是引用)的所有权,所以我们以后不能使用该值.同时,这也没有意义:我们本质上只传递一个可变的引用,之后游标无论如何都会超出范围.

我发现可以通过使用Cursor.into_inner()来"回收"引用,但手动操作感觉有点奇怪,因为在正常使用情况下,借阅判断器完全可以自己完成.

有比使用.into_inner()更好的解决方案吗?也许我对借书台还有什么不明白的?

推荐答案

通常,当您将可变引用传递给函数时,编译器会隐式执行reborrow.这就产生了一种生命周期 更短的新借款.

当参数为泛型(且不是&mut T形式)时,编译器不会自动执行此重新加载1.但是,您可以通过取消对现有可变引用的引用,然后再次引用它来手动执行此操作:

fn take_reference(data: &mut Vec<u8>) {
    {
        let mut buf = io::Cursor::new(&mut *data);

        use_cursor(&mut buf);
    }

    data.len();
}

1-这是因为当前的编译器体系 struct 只允许在强制站点上已知源类型和目标类型的情况下执行强制.

Rust相关问答推荐

使用InlineTables序列化toml ArrayOfTables

如何从铁 rust 中呼唤_mm_256_mul_ph?

Rust TcpStream不能在读取后写入,但可以在不读取的情况下写入.为什么?

在自身功能上实现类似移动的行为,以允许通过大小的所有者进行呼叫(&;mut;self)?

限制未使用的泛型导致编译错误

在0..1之间将U64转换为F64

使用关联类型重写时特征的实现冲突

失真图像图形捕获Api

你能在Rust中弃用一个属性吗?

为什么 tokio 在以奇怪的方式调用时只运行 n 个任务中的 n-1 个?

为相同特征的特征对象使用 move 方法实现特征

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

Rust并发读写引起的死锁问题

如何在 Rust 中按 char 对字符串向量进行排序?

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

我什么时候应该使用特征作为 Rust 的类型?

为什么具有 Vec 变体的枚举没有内存开销?

字符串切片的向量超出范围但原始字符串仍然存在,为什么判断器说有错误?

匹配结果时的简洁日志(log)记录

如何制作具有关联类型的特征的类型擦除版本?