有没有一种干净的方法可以在 Rust 插件中拥有全局可变状态?

ant*_*oyo 6 rust

我发现这样做的唯一方法是使用不安全的单例函数:

fn singleton() -> &'static mut HashSet<String> {
    static mut hash_map: *mut HashSet<String> = 0 as *mut HashSet<String>;

    let map: HashSet<String> = HashSet::new();
    unsafe {
        if hash_map == 0 as *mut HashSet<String> {
            hash_map = mem::transmute(Box::new(map));
        }
        &mut *hash_map
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?也许我们可以在plugin_registrar函数中做点什么?

通过全局可变状态,我的意思是一个可以被多个过程宏和/或属性使用的可变变量。

更新:

我正在编写一个编译器插件来提供sql!程序宏。我有一个#[sql_table]用于结构的属性,以便我可以获取 SQL 表的名称和列。

我需要全局可变状态来保存struct属性中的名称和字段,以便过程宏可以检查所有标识符是否存在。

Sim*_*pin 5

lazy_static!与具有全球宏观能够帮助将初始化也不是一成不变的。https://crates.io/crates/lazy_static/它的作用类似于您的if hash_map == 0 as *mut HashSet<String>,但会处理数据竞争,以防多个线程同时尝试执行此操作。

至于可变性,为了避免更多的数据竞争,您必须以某种方式保护它,可能使用Mutex.

全部一起:

#[macro_use] extern crate lazy_static;
use std::sync::Mutex;
use std::collections::HashSet;

lazy_static! {
    static ref THINGS: Mutex<HashSet<String>> = Mutex::new(HashSet::new());
}

fn usage() {
    // unwrap only fails if the lock is poisoned:
    // if another thread panicked while holding the lock.
    THINGS.lock().unwrap().insert("thing".to_owned())
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

1740 次

最近记录:

9 年,9 月 前