Ant*_*ony 6 lifetime rust trait-objects
任何人都可以通过以下代码告诉问题是什么?编译器抱怨生命周期,但错误消息绝对没有意义.我已经尝试了我能想到的一切,但似乎没有任何帮助.
use std::borrow::BorrowMut;
trait Trait<'a> {
fn accept(&mut self, &'a u8);
}
struct Impl<'a>{
myref: Option<&'a u8>,
}
impl<'a> Trait<'a> for Impl<'a> {
fn accept(&mut self, inp: &'a u8) { self.myref = Some(inp); }
}
fn new<'a>() -> Box<Trait<'a> + 'a> {
Box::new(Impl{myref: None})
}
fn user<'a>(obj: &mut Trait<'a>) {}
fn parent<'a>(x: &'a u8) {
let mut pool = new();
user(pool.borrow_mut());
}
Run Code Online (Sandbox Code Playgroud)
编译器错误是
error: `pool` does not live long enough
--> src/wtf.rs:22:10
|
22 | user(pool.borrow_mut());
| ^^^^ does not live long enough
23 | }
| - borrowed value dropped before borrower
|
= note: values in a scope are dropped in the opposite order they are created
Run Code Online (Sandbox Code Playgroud)
这绝对没有意义.借款人的生活如何?我甚至没有使用借来的价值!
DK.*_*DK. 10
好吧,这确实有意义,但由于终生的缺席而很难看到.所以,这是你的代码,明确地写出所有生命周期,并且无关紧要的细节被剔除:
use std::borrow::BorrowMut;
trait Trait<'a> {}
struct Impl<'a> {
myref: Option<&'a u8>,
}
impl<'a> Trait<'a> for Impl<'a> {}
fn new<'a>() -> Box<Trait<'a> + 'a> {
Box::new(Impl { myref: None })
}
fn user<'a, 'b>(obj: &'b mut (Trait<'a> + 'b)) {}
fn parent() {
/* 'i: */ let mut pool/*: Box<Trait<'x> + 'x>*/ = new();
/* 'j: */ let pool_ref/*: &'i mut Box<Trait<'x> + 'x>*/ = &mut pool;
/* BorrowMut<T>::borrow_mut<'d>(&'d mut Self) -> &'d mut T */
/* 'k: */ let pool_borrow/*: &'i mut (Trait<'x> + 'x)*/ = Box::borrow_mut(pool_ref);
user(pool_borrow);
}
Run Code Online (Sandbox Code Playgroud)
现在,从最后一行的角度来看parent,我们可以通过阅读user我们所拥有的生命周期的定义并替换它们的生命周期来计算出以下等价parent:
'a = 'x'b = 'i'b = 'x此外,这让我们得出结论:
'x = 'i这就是问题.由于您定义的方式user,您已经处于这样的情况:pool_ref借用的生命周期(等于pool您借用的存储位置的生命周期)必须与'x使用的生命周期相同事情被存储在pool.
它有点像Box能够在它存在之前有一个指向它自己的指针,这没有任何意义.
无论哪种方式,修复都很简单.更改user实际上有正确的类型:
fn user<'a, 'b>(obj: &'b mut (Trait<'a> + 'a)) {}
Run Code Online (Sandbox Code Playgroud)
这匹配由生成的类型new.或者,只是不要使用borrow_mut:
user(&mut *pool)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为它是"重新借用".调用borrow_mut或多或少地直接转换生命周期,但重新借用允许编译器将借用缩小到更短的生命周期.换一种方式,显式调用borrow_mut不允许编译器足够的自由来"忽悠"的寿命,使他们都排队,重新借贷做.
暂时不谈:
我甚至没有使用借来的价值!
无关紧要. Rust 完全在本地进行类型和生命周期检查.它永远不会看另一个函数的主体来看它正在做什么; 它仅在界面上进行.编译器不检查,也不关心,你在做什么内不同的功能.
| 归档时间: |
|
| 查看次数: |
599 次 |
| 最近记录: |