闭包是否可以返回对其拥有的数据的引用?

时间:2019-01-18 03:57:30

标签: rust closures ownership borrowing

如果我有一个闭包,则可以move || ...将数据移动到闭包上下文中,如下所示:

#[derive(Debug)]
struct State {
    value: usize,
}

fn external_receiver(mut inc: impl FnMut() -> usize) {
    let x = inc();
    println!("{:?}", x);

    let x = inc();
    println!("{:?}", x);
}

fn main() {
    let mut foo = Box::new(State { value: 0 });
    external_receiver(move || -> usize { 
        foo.as_mut().value += 1;
        return foo.as_ref().value;
    });
}

在某些情况下,使用闭包可以返回对某个数据对象的&mut State引用会很方便,在这种情况下,闭包的调用者对于对象的来源完全天真。

尽管如此,我还是无法工作:

#[derive(Debug)]
struct State {
    value: usize,
}

fn external_receiver(inc: impl Fn() -> &mut State) {
    let x = inc();
    x.value += 1;
    println!("{:?}", x);
}

fn main() {
    let mut foo = Box::new(State { value: 0 });
    external_receiver(move || -> &mut State { foo.as_mut() });
}

似乎没有什么明显的办法;我似乎无法弄清楚如何断言返回的引用(&'a mut State)的生存期应该等于闭包本身的生存期。

我尝试了几种变体,例如传递参考:

fn external_receiver<'a>(inc: &'a mut FnMut() -> &'a mut State) {
    let x = inc();
    x.value += 1;
    println!("{:?}", x);
}

fn main() {
    let mut foo = Box::new(State { value: 0 });
    let mut x = move || -> &mut State { foo.as_mut() };
    external_receiver(&mut x);
}

...但是我得到典型的:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:14:45
   |
14 |     let mut x = move || -> &mut State { foo.as_mut() };
   |                                             ^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime  as defined on the body at 14:17...
  --> src/main.rs:14:17
   |
14 |     let mut x = move || -> &mut State { foo.as_mut() };
   |                 ^^^^^^^^^^^^^^^^^^^^^
note: ...so that closure can access `foo`
  --> src/main.rs:14:41
   |
14 |     let mut x = move || -> &mut State { foo.as_mut() };
   |                                         ^^^
note: but, the lifetime must be valid for the call at 15:5...
  --> src/main.rs:15:5
   |
15 |     external_receiver(&mut x);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that argument is valid for the call
  --> src/main.rs:15:23
   |
15 |     external_receiver(&mut x);
   |                       ^^^^^^

将数据移动到封闭中实际上不会将数据移动到封闭本身中吗(即使封闭在盒子中?)?

是否有某种方法可以具有基本上Fn() -> &Foo做的功能?

0 个答案:

没有答案