如何使用相同的可变借用调用 serde_json::to_writer 两次?

2024-05-01

我正在尝试编写一个调用的函数serde_json::to_writer https://docs.serde.rs/serde_json/ser/fn.to_writer.html两次写两件事,但我不知道如何写。

这是一次尝试():

extern crate serde_json;

fn main() {
    let mut out = std::fs::File::create("out.txt").unwrap();
    write_stuff(&mut out);
}

fn write_stuff<W: ?Sized>(out: &mut W) -> Result<(), std::io::Error>
where
    W: std::io::Write,
{
    serde_json::to_writer(out, &1).unwrap();  // `out`: value moved here
    serde_json::to_writer(out, &2).unwrap();  // `out`: value used here after move
    Ok(())
}

Edit:找到了一种方法来编译,但是有没有更简单的方法():

extern crate serde_json;

fn main() {
    let mut out = std::fs::File::create("out.txt").unwrap();
    write_stuff(&mut out);
}

fn write_stuff<W: ?Sized>(out: &mut W)
where
    W: std::io::Write,
{
    write_wrapper(out);
    write_wrapper(out);
}

fn write_wrapper<W: ?Sized>(out: &mut W)
where
    W: std::io::Write,
{
    serde_json::to_writer(out, &1).unwrap();  
}

这种行为的原因有些微妙。当将共享引用作为参数传递给函数时,Rust 将简单地复制该引用。方式&T is Copy对全部T,因为我们可以同时拥有任意数量的共享引用。

另一方面,可变引用则不是Copy,因为在任何给定时间只能有其中一个。根据通常的 Rust 语义,对于非Copy类型,这意味着可变引用在作为参数传递时应该被移动。那么为什么这段代码可以工作呢?

fn foo(_: &mut i32) {}

fn main() {
    let mut i = 42;
    let r = &mut i;
    foo(r);
    foo(r);
}

原因是编译器创建了一个隐式重借每当它分配给显式声明为可变引用的变量时,函数调用都会转换为foo(&mut *r)。这将创建一个新的借用,该借用仅在函数调用期间持续,而原始引用r一旦重新借用的生命周期结束,就再次可用。

但是,仅针对使用可变引用类型显式声明的变量生成隐式重借用。如果我们改变定义foo()以上至

fn foo<T>(_: T) {}

代码将停止编译。现在的参数为foo()不再声明为可变引用,因此编译器不会引入隐式重借,并将移动所有权r而是在第一次调用时进入函数,导致第二次函数调用时出错。

您的代码中也会发生同样的情况。功能to_writer()被声明为

pub fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
where
    W: io::Write,
    T: Serialize,

自从争论以来writer未声明为可变引用,您需要创建显式重新借用以避免移动:

serde_json::to_writer(&mut *out, &1)?;

您在问题中给出的替代解决方案也有效 -write_wrapper()函数接收显式声明的可变引用作为参数,因此调用此函数会触发隐式重新借用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用相同的可变借用调用 serde_json::to_writer 两次? 的相关文章

随机推荐

  • Android:创建自定义形状进度条的最佳方法

    我想创建一个自定义形状的进度条 它会根据其进度改变颜色 但这几乎是一个不同的问题 那么 创建如下图所示的自定义形状进度条的最佳方法是什么 抱歉 MS Paint 绘图技巧不佳 为了拥有所有可能性 您应该创建一个从进度条派生的自定义类并完全重
  • MinGW支持MFC吗?

    我已经使用 MinGW 开发了 WinAPI 应用程序 没有出现任何问题 现在 我可以用 MFC 做同样的事情吗 我只是在这里猜测 但我认为您需要购买 Visual Studio 的副本才能获得使用 MFC 的许可证 MFC 也不因其对 C
  • 无限循环消耗 100% CPU

    我陷入了需要生成某个 Hz 的定义频率的情况 我尝试过多媒体计时器和互联网上提供的所有其他东西 但到目前为止 带有一些 if else 条件的无限循环给了我最好的结果 但这种方法的问题是它消耗了几乎所有的CPU 没有空间让其他应用程序正常工
  • 将 GDCM 图像转换为 Java BufferedImage

    我正在使用 GDCM 读取 DICOM 图像 有没有一种简单的方法可以使用 GDCM 读取 dicom 文件 然后将其转换为 Java BufferedImage 到目前为止我有以下内容 String filename C test dcm
  • 在本地运行 IPython Notebook 查看器

    我试图在我的工作中引入 IPython 笔记本 我想要做到这一点的方法之一是与同事分享我自己的笔记本工作 这样他们就能够看到创建复杂的报告并共享它们是多么容易 我显然无法使用笔记本查看器 因为我们的大部分工作都是保密的 我正在尝试在本地设置
  • DateField 未呈现为 type="date"

    class Form Form plan start DateField Plan Start validators Required 这段代码将渲染这个 html
  • ALL 的 SQL 参数

    我想知道SQL中是否有一个参数适用于所有 不是 例如 我现在正在编写一个搜索表 如果用户不在文本框中输入某些内容 则意味着忽略该特定参数并显示该字段的所有内容 我知道您可以为每种情况创建单独的 OLEDB 或 SQL 命令 并且它会起作用
  • 如何找出 gem 捆绑包将 gem 锁定在特定版本的原因?

    我正在尝试指定一个版本节俭宝石 http rubygems org gems thrift在我的宝石文件中 gem thrift gt 0 6 0 当我尝试跑步时bundle install 我收到此错误 You have requeste
  • UITextView分页启用文本截断

    我正在使用 UITextView 并启用分页 在 IB 中并以编程方式打开和关闭它 有很多文本 当启用分页滚动时 有时当前可查看文本的第一行和 或最后一行会在视图中的一半处结束 而在框架的底部或顶部则有一半在视图之外 因此您只能看到顶部或顶
  • 如何为已知行数创建具有无限列的 Angular Material Design 表?

    我创建了一个 HTML 表 它将生成无限的columns基于 数量rows在输入数据中 我尝试过使用这个帖子 https stackoverflow com questions 49868019 angular material table
  • 开发 Delphi Windows 7 应用程序的规则 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在哪里可以找到开发适用于 Windows 7 的 Delphi 应用程序时应遵循的最佳规则集 Marco 最近发表了 2 篇关于此主题的帖
  • 为什么 Asp.Net Core 2.1 WebApi 返回 500.19 错误?

    我有一个小型 webapi 服务 它可以在 Visual Studio 下工作 但不能在 IIS 下工作 我做了下一步 新应用程序已添加到 IIS 控制台中的默认网站 应用程序通过文件系统从 VS 发布到应用程序文件夹中 选择了依赖框架和可
  • 用于 MySQL 全文搜索的转义字符串

    我正在使用 Laravel 4 并设置了以下查询 if Input get keyword keyword Input get keyword search DB connection gt getPdo gt quote keyword
  • 在 Ruby 中,有没有办法重载初始化构造函数?

    在 Java 中你可以重载构造函数 public Person String name this name name public Person String firstName String lastName this firstName
  • 如何在 Gradle 构建中使用 S3 支持的 Maven 存储库的默认 AWS 凭证链?

    根据Gradle 文档 https docs gradle org 2 4 userguide dependency management html 示例 50 27 我们可以将 S3 支持的 Maven 存储库与 Gradle 2 4 一
  • 收到不明确符号的错误,需要帮助来删除它

    我收到此错误 无法在 Visual Studio 2010 中删除 我正在使用一个第三方库 该库使用自己的 字符串 定义 另外 Visual Studio 的 xstring 文件位于其安装的文件夹中 现在 当我尝试编译代码时 出现以下错误
  • 如何阻止诱变剂自动更新 ID3 版本?

    当我尝试在 MP3 中嵌入专辑封面时 诱变剂将 ID3 标签更新为版本 2 4 我不希望这样做 因为在 ID3v2 4 中 我的手机 运行 Windows Phone 8 和我的计算机无法识别标签 显然 只需更改mutagen id3 ve
  • 在 __device/global__ CUDA 内核中动态分配内存

    根据CUDA 编程指南 http developer download nvidia com compute cuda 3 2 prod toolkit docs CUDA C Programming Guide pdf 第 122 页 可
  • 如何根据文件位置运行钩子

    我参与了使用选项卡的 python 项目 但是我没有在我编写的所有其他代码中使用它们 在该特定项目中使用它们至关重要 项目位于特定目录下的一个目录中 IE main folder project1 project2 project3 etc
  • 如何使用相同的可变借用调用 serde_json::to_writer 两次?

    我正在尝试编写一个调用的函数serde json to writer https docs serde rs serde json ser fn to writer html两次写两件事 但我不知道如何写 这是一次尝试 extern cra