提问人:PauMAVA 提问时间:8/3/2021 更新时间:8/3/2021 访问量:578
延迟初始化和可变静态借用 [Rust]
Deferred initialization and mutable static borrowing [Rust]
问:
我的问题如下:
是否有可能对一个对象进行延迟初始化,然后将其借用为“静态生存期”
的可变对象?
一些背景
首先,我将举例说明我所说的延迟初始化。我提出的延迟初始化模型是将 crate 与一个包含 .这里有一个延迟初始化的示例。lazy_static
Mutex
Option<T>
use lazy_static::lazy_static;
use std::thread::JoinHandle;
use std::sync::Mutex;
pub struct DeferredStruct {
internal_field: u32,
}
impl DeferredStruct {
pub fn new(internal_field: u32) -> Self {
Self {
internal_field,
}
}
pub fn regular_function(&mut self) {
self.internal_field += 1;
println!("{}", self.internal_field);
}
}
lazy_static! {
static ref MY_DEFERRED: Mutex<Option<DeferredStruct>> = Mutex::new(None);
}
fn main() {
// Initial processing
// ...
// ...
// The value 10 would be obtained from a configuration file on runtime.
let deferred_struct = DeferredStruct::new(10);
let mut lock = MY_DEFERRED.lock().unwrap();
lock.replace(deferred_struct);
std::mem::drop(lock); // In this example we drop the lock to avoid a deadlock when calling another_function.
// More processing
// ...
// ...
let thread_handle = another_function();
thread_handle.join().unwrap();
}
// From another part of the program and possibly from another thread we
// lock MY_DEFERRED and call regular_funcion on it.
fn another_function() -> JoinHandle<()> {
std::thread::spawn(|| {
let mut lock = MY_DEFERRED.lock().unwrap();
if let Some(deferred) = lock.as_mut() {
deferred.regular_function();
}
})
}
您可以在 Rust Playground 中执行上述代码并检查它是否正确打印。11
引入需要静态生存期的结构函数
现在,假设我在里面添加了一个函数,该函数将创建一个工作线程,以便执行一些需要很长时间的计算:DeferredStruct
pub struct DeferredStruct {
internal_field: u32,
}
impl DeferredStruct {
pub fn new(internal_field: u32) -> Self {
Self {
internal_field,
}
}
pub fn regular_function(&mut self) {
self.internal_field += 1;
println!("{}", self.internal_field);
}
pub fn static_function(&'static mut self) {
std::thread::spawn(move || {
// Do something really long.
// Finally I make some changes on self
self.internal_field += 100;
});
}
}
在这种情况下,需要有生命周期:&mut self
'static
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement.
因此,该函数将采用 .&'static mut self
当试图借用 inside as 和 时,问题就来了。DeferredStruct
Option
MY_DEFERRED
'static
mut
如果我不能借钱,那么我就不能打电话.因为价值不会持续足够长的时间。'static
mut
deferred.static_function()
error[E0597]: `lock` does not live long enough
--> src/main.rs:57:33
|
57 | if let Some(deferred) = lock.as_mut() {
| ^^^^---------
| |
| borrowed value does not live long enough
| argument requires that `lock` is borrowed for `'static`
...
60 | })
| - `lock` dropped here while still borrowed
这里有一个最小的可重现的例子 Rust Playground。
TL;博士
是否可以借用在运行时创建的对象(不一定是在程序立即启动时创建的对象)作为可变的并且终身存在?Mutex<Option<T>>
'static
任何帮助都是值得赞赏的。
答: 暂无答案
上一个:如何改变静态引用?
评论
Box
的内容,以获取对运行时创建的对象的可变静态引用。