【问题标题】:vector of closures: cannot borrow `**h` as mutable, as it is behind a `&` referenceclsoures 的向量:不能将 `**h` 作为可变借用,因为它在 `&` 引用后面
【发布时间】:2021-11-10 21:29:01
【问题描述】:

我需要一个我声明的闭包向量,但由于编译错误,我无法使用该向量的项。

不能将**h 借用为可变的,因为它位于& 引用的后面

是否可以在没有动态内存分配的情况下使代码正常工作? 为什么 h 被借用为可变的?

fn main() {
    let hh: Vec<&dyn FnMut(&mut i32)> = vec![&|i: &mut i32| {
        *i = 10;
    }];

    let mut i = 0;
    let h = &hh[0];
    h(&mut i); // <-- cannot borrow `**h` as mutable, as it is behind a `&` reference
    println!("{}", i);
}

我已经使上面的示例有效,但在这种情况下,我需要为每个看起来过多的项目声明变量

fn main() {
    let mut item = |i: &mut i32| {
        *i = 10;
    };
    let mut hh: Vec<&mut dyn FnMut(&mut i32)> = vec![&mut item];

    let mut i = 0;
    let h = &mut hh[0];
    h(&mut i);
    println!("{}", i);
}

有没有优雅的解决方案?

【问题讨论】:

  • 如果您使用Fn 而不是FnMut,您的代码将编译。调用 FnMut 闭包需要对闭包的可变引用。

标签: rust


【解决方案1】:

如果你真的需要闭包是FnMut(它们具有持久状态),你可以Box向量中的闭包。

fn main() {
    let mut state = 0; // Gets move'd to stateful closure.
    
    let mut hh: Vec<Box<dyn FnMut(&mut i32)>> = vec![
        Box::new(move |i: &mut i32| {
            state += 2; // Closure now owns `state` and it persists.
            *i = state;
        })];

    let mut i = 0;
    let     h = &mut hh[0];
    
    h(&mut i);
    println!("{}", i); // Output: 2
    
    h(&mut i);
    println!("{}", i); // Output: 4
}

否则,如果闭包是 Fn(无状态),则代码与您尝试的类似。

fn main() {
    let hh: Vec<&dyn Fn(&mut i32)> = vec![&|i: &mut i32| {
        *i = 10;
    }];

    let mut i = 0;
    let     h = hh[0];
    h(&mut i); 
    println!("{}", i);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-17
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    相关资源
    最近更新 更多