“由于在生成器中使用而发生移动”错误是什么意思?

2024-04-09

我遇到了关于生成器的问题:

use tokio::runtime::Runtime;
use tokio::task::JoinHandle;
use std::sync::Arc;

pub fn run(f: Box<dyn Fn() -> Result<(), ()> + Send>) {
    f();
}

fn main() {
    let x = Arc::new(0);
    run(Box::new(move ||{
        let rt = Runtime::new().unwrap();
        let _t = rt.block_on(async move {
            let y = x;
        });
        Ok(())
    }));
}

Error:

error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
  --> src/main.rs:13:41
   |
10 |       let x = Arc::new(0);
   |           - captured outer variable
...
13 |           let _t = rt.block_on(async move {
   |  _________________________________________^
14 | |             let y = x;
   | |                     -
   | |                     |
   | |                     move occurs because `x` has type `Arc<i32>`, which does not implement the `Copy` trait
   | |                     move occurs due to use in generator
15 | |         });
   | |_________^ move out of `x` occurs here

我不明白为什么x是借用的,如果在闭包和块中,我使用move. So x应移至rt.block_on的关闭。根本不应该借钱。


发电机 https://doc.rust-lang.org/stable/unstable-book/language-features/generators.html是一个不稳定的功能,目前仅在 nightly 中可用,可以与其他语言中的生成器或协程进行比较(例如JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions, Go https://golangbot.com/goroutines/, Python https://wiki.python.org/moin/Generators).

生成器本质上是状态机,可以使用以下命令暂停执行yield然后再次恢复,并且可以在每次转换中传递数据。这种模式非常适合异步编程,并且 Rust 编译器扩展了某些async代码来使用生成器,即使在没有启用夜间功能的情况下您自己也无法显式地使用它们。

这些消息可能没有正确地进行功能门控,这可能是一个错误,或者它可能太复杂,无法为生成的代码呈现不同的错误async脱糖比您自己明确编写的代码要好。

因此,让我们忽略生成器,这对您的实际问题来说有点转移注意力。

你正在移动x进入闭包:

let x = Arc::new(0);
run(Box::new(move ||{
    // 'move' closure uses x so x is moved
}));

然后关闭动作x再次进入一个async堵塞。问题是签名run接受一个Fn闭包 - 不能修改其环境的闭包,但may被多次调用。然而,你提供的关闭移动x进入async第一次调用会阻塞,第二次调用就会无效。

既然你说过你无法改变run接受一个FnOnce,你需要做f通过阻止其移动来多次调用x。您可以通过克隆它来做到这一点:

fn main() {
    let x = Arc::new(0);
    run(Box::new(move || {
        let rt = Runtime::new().unwrap();
        // each time the closure is called, it will pass a clone of the Arc
        // into the task, so it can be called more than once
        let x = x.clone();
        let _t = rt.block_on(async move {
            let y = x;
        });
        Ok(())
    }));
}

整个设计的Arc是关于廉价克隆。它很便宜,因为它只复制指向数据的指针并增加引用计数,这就是它知道何时可以安全释放保存数据的内存的方式。如果您从未克隆过Arc那么你几乎肯定一开始就不需要它!

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

“由于在生成器中使用而发生移动”错误是什么意思? 的相关文章

随机推荐

  • 在 Android 中动态创建/删除按钮

    首先 如果这个答案已经在这里 我很抱歉 因为我已经搜索了几个星期 但还没有找到任何东西 我正在开发一个 Android 应用程序 它需要允许用户创建和删除按钮 我知道如何通过将按钮添加到 XML 文件并在 JAVA 文件中创建其功能来通常静
  • package.json 中的代理不影响 fetch 请求

    我正在尝试使用 React 从开发服务器获取一些数据 我正在运行客户端localhost 3001和后端port 3000 获取请求 const users fetch api users users then err res gt con
  • 将值设置为 Java 15 记录中的属性之一

    我在代码中使用Java 15预览功能记录 并定义记录如下 public record ProductViewModel String id String name String description float price 在控制器级别我
  • C++20 中是否有一个浮点数包装器,可以让我默认飞船运算符?

    我正在观看 使用 C 20 三路比较 Jonathan M ller Meeting C 2019 演讲 其中提到了包含浮点成员的类的问题 问题源于这样一个事实 涉及 NaN 的 IEEE 754 比较很奇怪 并且不提供总排序 Talk 提
  • 使用 tmap tm_bubble 添加固定大小的中断

    我正在尝试创建一个 tmap 气泡图 其中大小和颜色美观具有相同的固定中断 设置style fixed and breaks c Inf seq 10 10 by 2 5 Inf 正在为颜色变量生成所需的结果 但大小变量保持不变 我正在处理
  • 在同一个类中使用两个 UIPickerView

    我为第一个 UIPickerView 编写了这段代码 void viewDidLoad NSURL url NSURL URLWithString http localhost 8080 Data resources converter c
  • C#:通过 200 万个对象进行内存高效搜索,无需外部依赖

    我需要能够搜索集合大约 200 万个 C 项目 搜索应该可以在多个字段上进行 简单的字符串匹配就足够了 使用外部依赖项 例如数据库不是一个选择 但是使用内存数据库就可以了 主要目标是做到这一点内存效率高 集合中的类型非常简单 没有长字符串
  • 如何找到 toast 小部件的布局参数?

    我喜欢的布局toastwidget非常多 这意味着圆角 透明度 浅灰色边框 有没有办法查看像这样的android标准小部件的布局参数toast 我想定义一个TextView具有相同的布局参数 布局可以在下面找到 SDKBASEDIR pla
  • 如何在 ASP.NET C# 中发送电子邮件

    我对这个很陌生ASP NET http en wikipedia org wiki ASP NETC 区域 我计划通过 ASP NET C 发送邮件 这是SMTP http en wikipedia org wiki Simple Mail
  • 使用 Google+ API 获取用户凭据

    我正在尝试包括谷歌登录在我的android应用程序中使用谷歌 API 我可以从用户那里获取帐户详细信息 但登录后我会得到null when 请求用户名使用调用 Plus PeopleApi getCurrentPerson mGoogleA
  • 错误QApplication:没有这样的文件或目录

    我已经安装了具有 Qt 的 C SDK 但是当我尝试编译链接 QApplication 的代码时 它给了我错误 Error QApplication no such file or directory 我如何链接这些库 我搜索目录 有一个名
  • javascript 文件缓存的依据是什么?

    javascript 文件在什么基础上被缓存 假设我从一个网站加载一个名为 m script js 的文件 而在另一个网站上我使用相同的名称 m script js 但内容不同 浏览器会获取新的名称 还是只是查看名称并从缓存中加载它 两个
  • 检查位掩码的特定位

    我正在与Bitmasks in python 据我所知 这些是整数数组 当它们解压缩为二进制格式时 它们会告诉您数组中给定元素的 32 位中的哪一个被设置 1 我想知道检查数组的任何元素是否设置了 4 个特定位的最快方法 我不关心其余的 我
  • 更改所选单选按钮标签的样式

    我试图在表单中选择单选按钮标签时更改其边框颜色 我发现这个问题几乎正是我想要做的 CSS 如何设置选定单选按钮标签的样式 https stackoverflow com questions 4641752 css how to style
  • 程序太大

    我收到此错误消息 Procedure too large 在 VBA 中 这个错误的原因和解决办法是什么 您可能有一个或多个巨大的过程 函数 我认为 VBA 每个过程的限制为 64k 或其他值 您可以通过将该过程拆分为多个过程来修复此问题
  • 从 pandas.DataFrame 的每一列中获取最高值

    这是我的pandas DataFrame import pandas as pd data pd DataFrame first 40 32 56 12 89 second 13 45 76 19 45 third 98 56 87 12
  • Rails 加入多态关联

    我有一个名为的多态关联Notifiable在一个名为Notifiaction module Notifiable def self included base base instance eval do has many notificat
  • 泛型编程是多态性的一个例子吗?

    我正在做一项家庭作业 一个项目 其中一个标准是我必须以一种显着提高代码整体质量或功能的方式使用多态性 我做了一个哈希表 如下所示 public class HashTable
  • 垂直居中,右对齐,多行文本在绝对定位的 div 中,具有 Flexbox 父级

    我有一些绝对定位的 div 有两行文本 一个 h2 和一个 p 我试图让文本 在绝对定位的 div 内垂直居中 右对齐 并且 h2 和 p 标签之间有一个换行符 绝对定位的 div 包含在父级中 所以我想我可以使用 flexbox 来解决这
  • “由于在生成器中使用而发生移动”错误是什么意思?

    我遇到了关于生成器的问题 use tokio runtime Runtime use tokio task JoinHandle use std sync Arc pub fn run f Box