【问题标题】:Why does serde::json need to copy this ref? [duplicate]为什么 serde::json 需要复制这个 ref? [复制]
【发布时间】:2023-01-26 22:18:07
【问题描述】:

这是一些看起来应该有效的简单代码:

use serde_json;
use std::io::Write;

fn test(writer: &mut dyn Write) {
    serde_json::to_writer(writer, "test1").unwrap();
    serde_json::to_writer(writer, "test2").unwrap();
}

但它会产生以下错误:

error[E0382]: use of moved value: `writer`
  --> src/main.rs:35:27
   |
33 | fn test(writer: &mut dyn Write) {
   |         ------ move occurs because `writer` has type `&mut dyn std::io::Write`, which does not implement the `Copy` trait
34 |     serde_json::to_writer(writer, "test1").unwrap();
   |                           ------ value moved here
35 |     serde_json::to_writer(writer, "test2").unwrap();
   |                           ^^^^^^ value used here after move

为了让它工作,我必须跳过这个圈:

fn test(writer: &mut dyn Write) {
    serde_json::to_writer(&mut *writer, "test1").unwrap();
    serde_json::to_writer(writer, "test2").unwrap();
}

这里发生了什么?为什么我可以通过取消引用/重新引用来“手动”复制引用,但它没有实现复制?


这与 serde_json::to_writer 的通用类型签名特别有关,因为它也适用于不同的功能:

fn test(x: &mut dyn Write) {
    x.write_all(b"test1").unwrap();
    x.write_all(b"test2").unwrap(); 
}

【问题讨论】:

  • TL/DR 重复项:当编译器期望显式 &mut 引用(如第二个示例)时,Rust 隐式重新借用,但 serde_json::to_writer 采用泛型。

标签: rust serde-json


【解决方案1】:

在 Rust 中 &T 实现了 Copy。但是,&mut T 没有。必须搬走(因为Aliasing NAND Mutability

在您的情况下,writer&mut T 移出到 serde_json::to_writer 之后,该引用无法用于另一个调用。然而,为了方便起见,Rust 允许在简单的情况下从可变引用中可变地借用——前提是这种借用会在使用原始可变引用之前终止。这就是您在问题中所做的,您可以将其视为“临时可逆所有权转让”

尝试以其他方式使用它会失败。例如,在消除二次借用之前,这个使用了原始的可变引用。

fn test(writer: &mut dyn Write) {
    let mut w = &mut *writer;
    serde_json::to_writer(writer, "test1").unwrap();
    serde_json::to_writer(w, "test1").unwrap();
}

error[E0505]: cannot move out of `writer` because it is borrowed
 --> src/main.rs:6:27
  |
5 |     let mut w = &mut *writer;
  |                 ------------ borrow of `*writer` occurs here
6 |     serde_json::to_writer(writer, "test1").unwrap();
  |                           ^^^^^^ move out of `writer` occurs here
7 |     serde_json::to_writer(w, "test1").unwrap();
  |                           - borrow later used here

而这个尝试同时创建多个临时可变借用

fn test(writer: &mut dyn Write) {
    let mut w = &mut *writer;
    let mut w1 = &mut *writer;
    serde_json::to_writer(w, "test1").unwrap();
}
error[E0499]: cannot borrow `*writer` as mutable more than once at a time
 --> src/main.rs:6:18
  |
5 |     let mut w = &mut *writer;
  |                 ------------ first mutable borrow occurs here
6 |     let mut w1 = &mut *writer;
  |                  ^^^^^^^^^^^^ second mutable borrow occurs here
7 |     serde_json::to_writer(w, "test1").unwrap();
  |                           - first borrow later used here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 2017-09-08
    相关资源
    最近更新 更多