How do I return a boxed closure from a method that has a reference to the struct?

Deadly 提交于 2019-12-04 10:44:07

In general, you can specify the lifetime of a boxed trait object by writing Box<Trait + 'a> and analogously for trait objects behind other kinds of pointers (if it's omitted, it defaults to 'static at least in the case of Box). So in this specific case you want the return type Box<(Fn(i32) -> i32) + 'a>.

However, when you do that you will see another error about self not living long enough. The reason is that (without move) the closure will capture a reference to the local variable self. The solution is to use move. This does not move the Returner object, it moves self which is a reference to the Returner object.

In summary:

struct Returner {
    val: i32,
}

impl<'a> Returner {
    fn get(&'a self) -> Box<Fn(i32) -> i32 + 'a> {
        Box::new(move |x| x + self.val)
    }
}

As said in an existing answer:

  1. Add a lifetime that ties the lifetime of self to the lifetime of the returned value.
  2. Move the reference to self into the closure.

Since Rust 1.26, you no longer need to return a boxed closure if you are only returning a single type. Instead, you can use impl Trait:

impl Returner {
    fn get<'a>(&'a self) -> impl Fn(i32) -> i32 + 'a {
        move |x| x + self.val
    }
}

See also:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!