我在写一个玩具操作系统。我无法修复以下生命周期错误。
由于does not live long enough
error[E0597]: `fb_config` does not live long enough
--> src/main.rs:37:45
|
26 | pub extern "sysv64" fn kernel_main (mut fb_config: FrameBufferConfig) -> ! {
| ------------- has type `FrameBufferConfig<'1>`
...
37 | let mut pixel_writer = PixelWriter::new(&mut fb_config);
| -----------------^^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `fb_config` is borrowed for `'1`
...
66 | }
| - `fb_config` dropped here while still borrowed
这是我内核代码的一部分。FrameBufferConfig
具有寿命,并且是可变的,借用了PixelWriter::new()
。PixelWriter
也有一个生命周期,它有传递的FrameBufferConfig
作为成员。
// src/main.rs
pub extern "sysv64" fn kernel_main (mut fb_config: FrameBufferConfig) -> ! {
let mut pixel_writer = PixelWriter::new(&mut fb_config);
...
}
pub struct FrameBufferConfig<'a> {
pub frame_buffer: FrameBuffer<'a>, // https://docs.rs/uefi/0.3.2/uefi/proto/console/gop/struct.FrameBuffer.html
...
}
pub struct PixelWriter<'a> {
fb_config: &'a mut FrameBufferConfig<'a>,
pixel_writer: unsafe fn(&mut FrameBuffer, usize, Rgb),
}
impl<'a> PixelWriter<'a> {
pub fn new(fb_config: &'a mut FrameBufferConfig<'a>) -> Self {
...
PixelWriter {
fb_config,
pixel_writer,
}
}
恕我直言,PixelWriter
应该比FrameBufferCOnfig
活得更长。它看起来fb_config
(在kernel_main
的参数中定义)和PixelWriter
(在kernel_main
中定义)都处于活动状态,直到kernel_main
结束。所以我觉得fb_config
活得够久了。
- 限制
PixelWriter
的生存期。但它失败了。我们得到相同的错误。
pub extern "sysv64" fn kernel_main (mut fb_config: FrameBufferConfig) -> ! {
{
let mut pixel_writer = PixelWriter::new(&mut fb_config);
} // PixelWriter dropped?
...
} // fb_config dropped?
- 将owner移动到本地值。它传递编译。但这是多余的。
pub extern "sysv64" fn kernel_main (mut fb_config: FrameBufferConfig) -> ! {
let mut tmp = fb_config; // move owner here.
let mut pixel_writer = PixelWriter::new(&mut tmp);
...
}
你知道为什么会发生这个错误吗?既然我是生锈的初学者,我犯了一辈子的错误吗?谢谢你的帮助!
fb_config: &'a mut FrameBufferConfig<'a>,
你已经过度限制了这个生命周期。
&'a mut FrameBufferConfig
表示'a
指定该FrameBufferConfig
被借用多长时间-FrameBufferConfig
将至少被借用'a
。FrameBufferConfig<'a>
意味着'a
指定了FrameBufferConfig
内部引用的生命周期,因此FrameBufferConfig<'a>
不能超过'a
。
把这两个放在一起需要编译器得出结论,在PixelWriter::new(&mut tmp)
被执行后,FrameBufferConfig
被借用了剩余的存在(因为如果'a
结束,FrameBufferConfig<'a>
就不再有效,但是FrameBufferConfig
不能停止被借用,直到'a
结束),因此永远不能丢弃或以任何方式使用。
一般来说,当涉及到可变引用时,您将更需要使用不同的生命周期(&'a mut Foo<'a>
几乎总是无用的)。一个简单的原则(不是最优的,但是一个开始的地方)是为每个涉及的&mut
使用单独的生命周期,或者为所有涉及的&mut
使用单独的生命周期。(具体走哪条路取决于具体情况。)在您的示例中,我们只需要为两个角色设置两个生命周期:
pub struct PixelWriter<'fb, 'gop> {
fb_config: &'fb mut FrameBufferConfig<'gop>,
...
(为了保持一致性,我从库文档中取了生命周期名称'gop
)
也有可能(取决于你的程序需要)PixelWriter
应该拥有fb_config
,而不是对它有一个可变的引用,即
pub struct PixelWriter<'gop> {
fb_config: FrameBufferConfig<'gop>,
...
但是这是否合适取决于你的程序需要是什么。特别是,如果你要从一个FrameBufferConfig
顺序地创建多个PixelWriter
,引用可能是合适的,但是如果你要为每个FrameBufferConfig
只创建一个,那么所有权会简化事情。