无法从关闭返回值中移出借来的内容

我在一个中型项目上发现了这个问题。 下面的片段是这个问题的最小摘要。

在下面的代码中 , 我试图将枚举变量的列表映射为一组不同的枚举变量。 我使用一个闭包 , 这样我可以捕获一个可变引用到 my_list , 它是一个枚举变体的列表。 然后将闭包保存在 MyType 实例中 , 以便以后调用 , 并将结果用于其他方法。

为了保持关闭, 我在 Box 中使用了 FnMut 特征。 我也把它包在 Option 中 , 这样我就可以在实例创建之后设置关闭。

我从这里提出的问题中得出了一点结论 : 使用盒装还是未装箱的

use std::collections::HashSet;

enum Numbers {
    One,
    Two,
    Three,
}

#[derive(Eq, PartialEq, Hash)]
enum Romans {
    I,
    II,
    III,
}

struct MyType<'a> {
    func: Option<Box<dyn FnMut() -> HashSet<Romans> + 'a>>,
}

impl<'a> MyType<'a> {
    pub fn set_func<F>(&mut self, a_func: F)
        where F: FnMut() -> HashSet<Romans> + 'a {
        self.func = Some(Box::new(a_func));
    }

    pub fn run(&mut self) {
        let result = (self.func.unwrap())();
        if result.contains(&Romans::I) {
            println!("Roman one!");
        }
    }
}

fn main() {
    let my_list = vec![Numbers::One, Numbers::Three];
    let mut my_type = MyType {
        func: None,
    };
    my_type.set_func(|| -> HashSet<Romans> {
        HashSet::from(my_list
            .iter()
            .map(|item| {
                match item {
                    Numbers::One => Romans::I,
                    Numbers::Two => Romans::II,
                    Numbers::Three => Romans::III,
                }
            })
            .collect()
        )
    });

    my_type.run();
}

当我试图编译时 , 我得到了以下错误 :

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:27:23
   |
27 |         let result = (self.func.unwrap())();
   |                       ^^^^^^^^^ cannot move out of borrowed content

error: aborting due to previous error

我不太明白为什么要搬出去。 它是隐藏的 self 吗? 结果 HashSet? 或者里面的值 ? 我做错了什么 ?


EN From: Cannot move out of borrowed content from closure return value

2 Comments

  1. 你遇到的麻烦是调用 unwrap消耗它 - - 它需要 self 作为一个参数。 在 run() 内部 , 您的 MyType 只引用了 &mut self 本身 , 因此它不能拥有它的字段。

    解决方案是将可变引用改为 :

        pub fn run(&mut self) {
            if let Some(func) = &mut self.func {
                let result = func();
                if result.contains(&Romans::I) {
                    println!("Roman one!");
                }
            }
        }
    
    1. 哈。 所以问题是 Option 部分。 在阅读了你的答案后, 我寻找 Option 文件。 已经有一个 as_mut 方法: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_mut 。 使代码简化了一点。

More articles:

  • 如何从常规关闭返回并停止执行 ?
  • 不理解带关闭的递归函数返回行为
  • 当两者都在关闭项的返回语句中时 , 扩展 JavaScript 类
  • 如果没有返回错误 , PHP 无法从远程路径获取文件内容
  • 无法在线程之间发送一个和 str , 因为它寿命不够长
  • 快速关闭中的任意链接 , 返回类型必须是 Void
  • 不能借用可变的"Box"内容
  • 无法从 php 函数返回数组到 ajax 请求
  • 代表迅速关闭
  • 如果默认关闭 jQuery ui 选项卡中的内容会被索引吗 ?
  • 坏状态 : 无法设置带有内容类型"应用程序/json"的请求的正文字段
  • 无法从我的应用程序外发送返回的对象
  • 没有数据库但保存了游标的内容提供程序 : 是否可以 / 需要关闭查询游标 ?
  • Q WebEngineering-View 在某些情况下无法正常关闭
  • 使用 json 内容类型关闭精简程序时出错
  • 在外部访问 jQuery 关闭函数
  • <string>我如何接受一个选项, 处理它, 并返回一个选项? </string></string>
  • 无法使用 OneDrive 为业务 API 将 / 上传内容放入 OneDrive 中的业务文件
  • 如何返回具有实现"读"和"写"特性的泛型类型的结构?
  • 将 DispatchTimers 改为其他计时器以解决性能问题。 无法更新 UI , 程序关闭
  • 无法比较 u8 和 u8
  • 无法关闭通过 dbus 打开的另一个应用程序双击
  • 在无法进行类型推断时使用. into
  • 无法关闭与活动连接的 ViewModel 中的 Realm 实例
  • 无法优雅地关闭 JMeter , 暂停
  • 不同类型的快速关闭语法 - 哪一种正确?
  • 无法在编写上下文中使用函数返回值
  • 无法在写入上下文中使用方法返回值 PHP 未设置 ()
  • 无法获得 ASP.NET MVC 6 控制器返回 JSON
  • 使用 MessageBox 单击"关闭按钮[X]时,如何返回值? (C #)