簡體   English   中英

是否有一種干凈的方法在Rust插件中擁有全局可變狀態?

[英]Is there a clean way to have a global mutable state in a Rust plugin?

我發現這樣做的唯一方法是使用不安全的單例函數:

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
    }
}

有沒有更好的辦法? 也許我們可以在plugin_registrar函數中做些什么?

通過全局可變狀態,我的意思是可以由多個過程宏和/或屬性使用的可變變量。

更新:

我正在編寫一個編譯器插件來提供一個sql! 程序宏。 我有一個#[sql_table]屬性用於結構,以便我可以獲取SQL表的名稱和列。

我需要全局可變狀態來保存屬性中struct的名稱和字段,以便過程宏可以檢查所有標識符是否存在。

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())
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM