rust中简单粗暴地使用global变量的方法

就是用unsafe
在Rust In Action中给出了两段代码

use rand::{random};
   
  static mut ERROR: isize = 0;
   
  struct File;
   
  #[allow(unused_variables)]
fn read(f: &File, save_to: &mut Vec<u8>) -> usize {
      if random() && random() && random() {
         unsafe {
             ERROR = 1;
         }
     }
     0
 }
  
 #[allow(unused_mut)]
 fn main() {
     let mut f = File;
     let mut buffer = vec![];
  
     read(&f, &mut buffer);
     unsafe {
         if ERROR != 0 {
             panic!("An error has occurred!")
         }
     }
 }

第二个例子,停机标志

#![cfg(not(windows))]

extern crate libc;

use std::time;
use std::thread::{sleep};
use libc::{SIGTERM, SIGUSR1};

static mut SHUT_DOWN: bool = false;

fn main() {
    register_signal_handlers();

    let delay = time::Duration::from_secs(1);

    for i in 1_usize.. {
        println!("{}", i);
        unsafe {
            if SHUT_DOWN {
                println!("*");
                return;
            }
        }

        sleep(delay);

        let signal = if i > 2 {
            SIGTERM
        } else {
            SIGUSR1
        };
        unsafe {
            libc::raise(signal);
        }
    }
    unreachable!();
}

fn register_signal_handlers() {
    unsafe {
        libc::signal(SIGTERM, handle_sigterm as usize);
        libc::signal(SIGUSR1, handle_sigusr1 as usize);
    }
}

#[allow(dead_code)]
fn handle_sigterm(_signal: i32) {
    register_signal_handlers();

    println!("SIGTERM");

    unsafe {
        SHUT_DOWN = true;
    }
}

#[allow(dead_code)]
fn handle_sigusr1(_signal: i32) {
    register_signal_handlers();

    println!("SIGUSR1");
}

如果不想用 unsafe代码,可以用 lazy_static! 宏

use lazy_static::lazy_static; 
use regex::Regex; 

lazy_static! {
    static ref RE: Regex = Regex::new(r"hello (\w+)!").unwrap();
}

fn main() {
    let text = "hello bob!\nhello sue!\nhello world!\n";
    for cap in RE.captures_iter(text) {
        println!("your name is: {}", &cap[1]);
    }
}

如果这个全局变量可变, 还需要加上Mutex(单个修改者)或者RwLock(多个修改者)

另外一个方法是 https://github.com/matklad/once_cell 据说正在提议加入std库中

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注