当临时借用闭包拥有的数据时,Rust“借用的数据逃逸到闭包之外”

问题描述 投票:0回答:1

这里是这个问题的游乐场。这里的代码以一种非常迂回的方式做一些事情,但它是问题的最小重现,仍然有点类似于我的实际程序——我知道它可以很容易地修改以工作并实现相同的事情。

问题:此错误在此上下文中意味着什么?为什么不允许这样做?

看起来“a”由闭包拥有,并且 a.make_borrower() 创建了一个可变借用“a”的临时结构。然后,在闭包结束之前删除该结构。这里的生命周期一定出了问题,但我可能对生命周期的工作方式没有足够深入的了解,无法看到它。

为了方便阅读,将代码粘贴在这里:

use core::marker::PhantomData;


struct A<B> {
    borrower_type: PhantomData<B>,
    something: Vec<i32>,
}

impl<'a, B: ABorrower<'a>> A<B> {
    pub fn make_borrower(&'a mut self) -> B {
        B::new(self)
    } 
}

trait ABorrower<'a>: Sized {
    fn new(a: &'a mut A<Self>) -> Self;
    fn borrow(&mut self) -> &mut A<Self>;
}


struct SomeABorrower<'a> {
    a_ref: &'a mut A<Self>,
}
impl<'a> ABorrower<'a> for SomeABorrower<'a> {
    fn new(a: &'a mut A<Self>) -> Self { Self { a_ref: a } }
    fn borrow(&mut self) -> &mut A<Self> { self.a_ref }
}


fn main() {
    let mut a = A::<SomeABorrower> {
        borrower_type: PhantomData,
        something: vec![1, 2, 3, 4, 5],
    };
    
    let mut closure = move || {
        a.something[1] += 2;
        {
            let a_borrower = a.make_borrower();
            a_borrower.a_ref.something[1] += 5;
        }
        a.something[1] -= 2;
    };
    
    for _ in 0..100 {
        closure();
    }
}
rust lifetime borrow-checker
1个回答
0
投票

我想我已经弄清楚为什么会出错:

在我的示例中,一开始就初始化 A:: {...} 将 SomeABorrower<'a> 的生命周期 'a 设置为外部作用域。因此,当我通过执行 a.borrow() 创建 SomeABorrower 时,它会将创建的引用视为在闭包外部的范围内一直有效,从而创建一个可能在闭包外部使用的对闭包中拥有的内容的引用(因此“逃脱”关闭)。

© www.soinside.com 2019 - 2024. All rights reserved.