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
。就我对可变性的解释而言。。。这超出了我的控制,因为第三方库强制执行该要求。