如何处理将可变借用的结构传递给函数闭包?

时间:2019-07-31 20:02:04

标签: testing rust closures ownership

我正在使用proptest板条箱在no_std环境中运行一些属性测试。 proptest的默认test_runner::TestRunner::run()实现接受一些输入(作为proptest中定义的StrategyValueTree对象)和函数闭包作为参数,因此您可以使用所需的值运行许多测试价值树或策略。

我需要测试将可变借用结构作为参数的函数调用。这不会编译:

error[E0596]: cannot borrow `*<obj>` as mutable, as it is a captured variable in a 'Fn' closure

obj是通过函数调用传递给test_runner的结构,它是一个可变的借用对象。

深入到抗议的源代码中,很明显,由于test_runner::TestRunner::run()的功能签名而导致编译错误:

pub fn run<S: Strategy>(
    &mut self,
    strategy: &S,
    test: impl Fn(S::Value) -> TestCaseResult,
) -> TestRunResult<S>

该参数必须为FnMut,以便捕获的变量可以在函数调用中可变。我的问题是:这样做有没有理想的锈蚀方法?

这是从条件编译的运行函数传递的函数:

fn test_mod(runner: &mut TestRunner, obj: &mut MyObjStruct) -> Result<(), TestError(u32)>>{
    runner.run(&(0x400_0000u32..0xe00_0000u32), |addr| {
        if mod::test::test_page_map(addr, obj).is_ok() {
            Ok(())
        } else {
            Err(TestCaseError::fail(Reason::from("Failed to map address")))
        }
    })
}

mod::test::test_page_map使用obj,在结构中使用相关的元数据,相应地更新该数据,并将页面映射到输入地址。它根据映射是否成功返回结果。值得注意的是,我无法克隆对象。

有人能解决与“锈病方法”相符的问题吗?在no_std领域中是否有诸如Cell之类的某种机制,或者我可以包装可变对象的东西,以便它具有内部可变性,但可以作为捕获变量传递给'Fn'闭包?我对Rust还是很陌生,所以不确定通常如何处理这种事情。

1 个答案:

答案 0 :(得分:0)

找到了一个可行的答案,尽管可能还有其他答案。我发现有效的方法是使用core::cell::RefCell::new(obj)包装对象。然后通过调用RefCell

提供的borrow_mut()方法,将RefCell包装的对象作为可变借项传递给函数。