【问题标题】:Rust closure as a method of structRust 闭包作为结构的一种方法
【发布时间】:2022-11-27 02:32:35
【问题描述】:

我怎样才能调用一个接收我的结构作为参数并将该闭包作为成员的闭包?

type Thunk = Box<dyn FnMut(&mut Config) + Send + 'static>;

struct Config {
    s: String,
    f: Thunk,
}

impl Config {
    fn run(&mut self) {
        // the problem is here
        (self.f)(self);
    }
}

fn main() {
    let cfg = Config {s: String::from("hello"), f: Box::new( |c| {
        println!("{}", c.s);
    }) };
}

提前致谢

【问题讨论】:

    标签: rust closures


    【解决方案1】:

    这通常是不可能的,因为 Rust 安全规则——回调在调用期间专门借用自己,所以你不能同时再次借用整个结构。

    要了解为什么这不仅仅是一个理论问题,请考虑以下问题:

    type Thunk = Box<dyn FnMut(&mut Config) + Send + 'static>;
    
    struct Config {
        s: String,
        f: Thunk,
    }
    
    impl Config {
        fn run(&mut self) {
            // the problem is here
            (self.f)(self);
        }
    }
    
    fn main() {
        let s = String::from("temporary");
        let cfg = Config {s: String::from("hello"), f: Box::new(move |c| {
            c.f = Box::new(|_| {});
            println!("{}", s);
        }) };
    }
    

    在这段代码中,我们有回调,它在运行时本质上会自行删除。由于它通过移动捕获s,因此s与回调一起被丢弃。然后回调尝试打印s——如果允许的话,我们就有了释放后使用。


    解决方案将取决于实际要求。最简单的方法是分离配置,仅将不包含 Trunk 本身的部分传递给 Trunk

    【讨论】:

      猜你喜欢
      • 2017-04-26
      • 2020-02-22
      • 2015-03-06
      • 1970-01-01
      • 2020-07-18
      • 2021-09-05
      • 1970-01-01
      相关资源
      最近更新 更多