C++ 将Cpp转换为Rust,处理全局静态对象

C++ 将Cpp转换为Rust,处理全局静态对象,c++,rust,static,global,lazy-static,C++,Rust,Static,Global,Lazy Static,我是一个初学者,将一个熟悉的Cpp项目翻译成Rust。该项目包含一个名为Globals的类,该类存储全局配置参数。以下是其cpp文件的摘录: static Globals &__get() { static Globals globals; return globals; } const Globals &Globals::get() { auto &globals = __get(); if (!globals.initialized) { t

我是一个初学者,将一个熟悉的Cpp项目翻译成Rust。该项目包含一个名为Globals的类,该类存储全局配置参数。以下是其cpp文件的摘录:

static Globals &__get()
{
  static Globals globals;
  return globals;
}

const Globals &Globals::get()
{
  auto &globals = __get();
  if (!globals.initialized) {
    throw std::runtime_error("Initialize globals first");
  }
  return globals;
}

void Globals::set(const Globals &globals)
{
  __get() = globals;
}

我该如何将其转化为生锈?据我所知,get实现了某种单例逻辑。我已经读过关于lazy_static板条箱的文章来实现类似的功能,但是每次我想读取它的值时解锁变量似乎太冗长了。在cpp代码中使用Globals::get这样的接口不可能实现这一点吗

我很少发帖,所以如果我忘了什么,就告诉我,我会提供细节。谢谢

我已经读过关于lazy_static板条箱的文章来实现类似的功能,但是每次我想读取它的值时解锁变量似乎太冗长了

有一个很好的理由:安全防锈包括你所谓的螺纹设计安全。一个不受保护的可变全局变量是非常不安全的

哪个。。。这就是为什么与可变静态进行交互需要不安全的读写操作

< > C++中的翻译非常简单(0),并且可以很容易地推断出,唯一真正的分歧是必须初始化锈静态。 还要注意的是,如果你不需要变异,那么你就可以偷懒了!一个只读值,您根本不需要互斥,也不需要解锁任何东西


[0]尽管通过消除不必要的uu get

而大大简化了安全代码中的锈蚀需要内存安全-因此,安全代码中不能有可变静态。例如,您可以使用原子静态,但对于普通类型,您将需要某种锁定机制,例如,或者如果性能是您的事情,那么板条箱提供的实现比Rust标准库更高性能

如果您不想自己处理锁定,我可以建议使用getter/setter方法创建包装器对象吗

使用std::sync::{Arc,RwLock}; 使用一次\单元::同步::懒惰; 静态全局:Lazy=Lazy::newGlobal::new; 结构GlobalThingymajig{ 酒吧编号:u32, pub单词:String, } pub-struct-GlobalArc; impl全球{ 酒吧fn新->自我{ SelfArc::newrBlock::new 环球金马吉酒店{ 编号:42, 单词:生命、宇宙和一切的答案 } } 发布fn编号和自我->u32{ self.0.read.unwrap.number } pub fn words&self->String{ self.0.read.unwrap.words.clone } 发布fn设置编号和自我,新编号:u32{ 让mut writer=self.0.write.unwrap; writer.number=新的_编号; } pub fn set_words和self,new_words:String{ 让mut writer=self.0.write.unwrap; writer.words=新词; } }
这回答了你的问题吗?在某种程度上,最大的区别是我的全局结构是不可变的,因此应该可以安全地读取,并且我猜也不需要互斥锁?。然而,lazy_static需要实现Sync特性,我明白为什么,但在我的例子中,它没有意义。这个怎么样@Moostropfen集合的存在使你的全局可变。它可能只是暂时可变的,例如在程序开始时设置一次,但Rust无法知道这一点。另外,虽然第一个链接包含可变全局变量,但它也隐含了设置一次然后仅访问的功能:这适用于lazy_static和once_cell。。我可能使用了一个选项,而不是在Globals中有一个指示初始化状态的标志,这使它有点过于复杂了,因为这意味着您无法直接从get返回rwlockdeadguard,所以我不得不使用其中的一些想法来包装它。