在编译我对Firecracker (在aarch64上,但我怀疑这个问题是否与架构相关)所做的更改时,我遇到了一个终生错误:
error[E0716]: temporary value dropped while borrowed
--> src/vmm/src/device_manager/mmio.rs:174:24
|
174 | let int_evt = &serial
| ________________________^
175 | | .lock()
176 | | .expect("Poisoned legacy serial lock")
| |__________________________________________________^ creates a temporary which is freed while still in use
177 | .interrupt_evt();
| - temporary value is freed at the end of this statement
178 | vm.register_irqfd(int_evt, self.irq)
| ------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value原始代码(编译良好)是:
vm.register_irqfd(&serial
.lock()
.expect("Poisoned legacy serial lock")
.interrupt_evt(), self.irq)
.map_err(Error::RegisterIrqFd)?;我不明白这有什么区别。错误消息似乎表明expect()正在返回临时值,并且我正在获取对它的常量引用,在C++中,这会延长临时值的生命周期,不是吗?无论哪种方式,为什么它在原始代码中可以工作,但在我绑定了一个l值之后就不行了(按照C++的说法,我不确定它是否也适用于Rust值)?
我尝试在这里创建一个SSCE,但它如预期的那样工作!
发布于 2020-04-04 20:53:25
问题的一个简单的、可重现的例子(playground):
// create array inside mutex
let mutex = Mutex::new([ 0i32 ]);
// get reference to item inside array
let item: &i32 = mutex.lock().unwrap().get(0).unwrap();
// use reference for something
println!("item = {:?}", item);mutex.lock().unwrap()返回一个MutexGuard<'_, Option<i32>>,它借用互斥锁内部的数据。它还拥有对数据的锁定,该锁定在解除守卫时释放,这意味着其他任何人都不能同时借用数据。
当您在该防护上调用内部类型的方法时(如上面示例中的.get,或代码中的.interrupt_evt ),它将在防护的生命周期内借用,因为您只能在防护存在的情况下安全地访问数据。但是防护并不存储在任何变量中,因此它只对该语句临时存在,并在语句结束时立即删除。因此,您不能在语句之外获得对数据的引用。
要解决这个问题非常简单:首先将卫士存储在变量中,然后从变量中借用。这将确保保护的寿命比您从它获得的引用(playground)更长:
// create array inside mutex
let mutex = Mutex::new([ 0i32 ]);
// get reference to item inside array
let guard = mutex.lock().unwrap();
let item: &i32 = guard.get(0).unwrap();
// use reference for something
println!("item = {:?}", item);
// guard is now destroyed at end of scope
// and mutex lock is released herehttps://stackoverflow.com/questions/61027885
复制相似问题