Rust 在运行时使用不能声明为静态的函数初始化可变静态变量 使用std::sync::一次; 结构存储; impl商店{ fn new()->Store{ 贮藏{ 清单:RwLock::new(/*…*/),//@注意:RwLock不实现克隆 } } fn保存(&mut self){ // ... } }
失败代码:Rust 在运行时使用不能声明为静态的函数初始化可变静态变量 使用std::sync::一次; 结构存储; impl商店{ fn new()->Store{ 贮藏{ 清单:RwLock::new(/*…*/),//@注意:RwLock不实现克隆 } } fn保存(&mut self){ // ... } },rust,ffi,lifetime,Rust,Ffi,Lifetime,失败代码: 静态mut存储:Option=None; 静态初始化:Once=Once::new(); 不安全{ 初始化调用|一次(||){ store=Some(store::new()); }); store.unwrap().save();//错误:无法移出静态项`store` } 错误很简单,但这是我迫切需要完成的事情,因为Store::new()在幕后做了大量计算代价高昂的工作 我要求的似乎是不可能的:声明一个类型为Store的静态变量,并在运行时初始化它——因为new不能static
静态mut存储:Option=None;
静态初始化:Once=Once::new();
不安全{
初始化调用|一次(||){
store=Some(store::new());
});
store.unwrap().save();//错误:无法移出静态项`store`
}
错误很简单,但这是我迫切需要完成的事情,因为Store::new()
在幕后做了大量计算代价高昂的工作
我要求的似乎是不可能的:声明一个类型为Store
的静态变量,并在运行时初始化它——因为new
不能static
,因为该函数中发生了绝对关键的内部易变性。此外,rBlock
是一项要求,无法克隆。我敢问,这是否可以用线程安全的方式实现
由于程序中的后续函数调用(在其他方面不相关)依赖于函数调用,因此不能延迟新的函数调用或其内部属性
为了使问题更加清楚,这是在外国金融机构的背景下进行的。我无法控制程序的生命周期,也无法以更安全的方式管理此变量。尽管如此,我还是希望这个存储
变量在程序的整个生命周期内都有效
我的问题是概念性的。我绝对不希望这个确切的代码被稍微修改并突然编译。我在这里问一个问题,因为我无法思考如何才能实现我想要的。我试过其他几种方法。。。这是迄今为止我所做的最好的尝试。很难确定没有MCVE你想要什么,但以下是我所做的 首先,正如编译器所说,您的问题非常简单:
unwrap
使用该选项,而您不能使用静态。然而,你真正想要的似乎是在适当的地方对商店进行变异,这是可能的,甚至有几种方式
我选择的是下面这个。一般来说,要在适当的地方变异某些东西,我们必须得到对它的唯一引用。根据Option的文档,有,它将&mut Option
转换为Option
。重要的一点是,这个新选项是自有的,即它不是存储在static中(而是引用static),因此它可以被unwrap
使用,产生必要的&mut
引用,我们可以调用save
:
fn main() {
unsafe {
INIT.call_once(|| {
store = Some(Store::new());
});
store.as_mut().unwrap().save();
}
}
有可能实现你的目标
但是,我不太确定您使用
静态mut
是否合理。首先,我们完全不清楚为什么需要在保存
中使用&mut self
:如果存储
中只有RwLock
,那么共享引用就可以了,因为这就是锁定的重点。在这种情况下,您可以简单地将store
(双关语)存储在lazy\u static
:
// skipping definitions
use lazy_static::lazy_static;
lazy_static! {
static ref store: Store = Store::new();
}
fn main() {
store.save();
}
我是否正确理解您想要一个初始化相当复杂的
静态变量?您只需要在第一次访问发生之前的某个时间运行初始化就可以了吗?或者你需要在运行main
之前初始化你的static吗?@LukasKalbertodt没有main,这是ffi。你回答的第一部分就是我需要的。具体地说,as_mut
。就我对可变性的解释而言。。。这超出了我的控制,因为第三方库强制执行该要求。