【问题标题】:Parsing data into a module-level mutable static variable将数据解析为模块级可变静态变量
【发布时间】:2015-03-03 05:51:31
【问题描述】:

我在一个模块中有一组函数需要访问一些共享的初始化时间状态。实际上,我想用静态可变向量对此进行建模,例如:

static mut defs: Vec<String> = vec![];

fn initialize() {
    defs.push("One".to_string());
    defs.push("Two".to_string()); 
}

(例如:http://is.gd/TyNQVv,失败并显示“不允许可变静态有析构函数”。)

我的问题类似于Is it possible to use global variables in Rust?,但使用Vec(即带有析构函数的类型),因此基于Option 的解决方案似乎不适用于该问题。也就是说,这与我第一次尝试的错误相同:

static mut defs: Option<Vec<String>> = None;

fn initialize() {
    let init_defs = vec![];
    init_defs.push("One".to_string());
    init_defs.push("Two".to_string()); 
    defs = Some(init_defs);
}
  1. 有没有办法访问在初始化时填充并在运行时可见的静态(“全局”)向量?

  2. 我是否应该考虑其他模式来支持此用例?传递对状态向量的显式引用是可能的,但会混淆大量需要访问此状态的函数签名。

【问题讨论】:

    标签: static rust mutability


    【解决方案1】:

    您可以为此使用lazy_static

    lazy_static! {
        static ref defs: Vec<String> = {
            let mut init = vec!["One".to_string(), "Two".to_string()];
            // init.push(...); etc. etc.
            init
        }
    }
    

    在第一次访问时初始化一个向量,之后它是不可变的。如果您希望稍后对其进行修改,请将其包装在 std::sync::Mutex 中是一个很好的第一步。

    还有其他我应该考虑的模式来支持这个用例吗?传递对状态向量的显式引用是可能的,但会混淆大量需要访问此状态的函数签名。

    要考虑的一种模式是创建一个上下文对象来存储函数所需的所有信息,例如

    struct Context {
        defs: Vec<String>
    }
    

    然后传递Context 确保每个人都知道他们需要知道什么。您甚至可以考虑将所有/许多/某些函数作为方法放在Context 上,例如

    impl Context {
        fn foo(&self) {
            if self.defs.len() > 10 {
                 println!("lots of defs");
            }
        }
        // ...
    }
    

    如果您需要修改上下文(自动确保线程安全)和/或如果您希望在单个进程中拥有多个独立实例,则此模式特别好。

    【讨论】:

    • 谢谢!这非常清楚地回答了我的两个问题。我特别喜欢使用 impl'd 方法的 Context 结构模式。这感觉更地道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 2023-03-22
    • 2021-08-19
    • 1970-01-01
    相关资源
    最近更新 更多