banner
orion

orion

中国科学技术大学研究生;数据库内核开发工程师;生产力爱好者;

How to define and use global variables in Rust

Introduction#

Rust is a safe and efficient systems programming language. Its syntax is similar to C, but it excels in terms of safety and concurrency. In Rust, defining and using global variables can help us share data in our programs, improving code reusability and maintainability. In this article, we will introduce how to define and use global variables in Rust.

Defining Global Variables#

In Rust, defining global variables requires the use of the static keyword. There are two ways to define global variables:

Defining Immutable Global Variables#

static GLOBAL_VAR: i32 = 42;

In the above code, we define a global variable named GLOBAL_VAR with a type of i32 and an initial value of 42. It is important to note that the type of the defined global variable must be specified. After defining an immutable global variable, we can read its value from anywhere in the program.

Defining Mutable Global Variables#

static mut GLOBAL_VAR: i32 = 42;

In the above code, we use static mut to define a mutable global variable named GLOBAL_VAR with a type of i32 and an initial value of 42. It is important to note that defining a mutable global variable requires the use of the mut keyword, and using a mutable global variable requires the use of the unsafe keyword.

Using Global Variables#

In Rust, using global variables requires the use of fully qualified paths. For example, in the global variable GLOBAL_VAR defined above, we can use its value from anywhere in the program:

fn main() {
    println!("{}", GLOBAL_VAR);
}

In the above code, we use a fully qualified path to access the value of the global variable GLOBAL_VAR and print it to the console.

Safety of Global Variables#

In Rust, the use of global variables requires special attention to concurrency safety. Since global variables can be used from anywhere in the program, they can potentially cause issues such as data races. To address these issues, Rust provides some special mechanisms to ensure the safety of global variables.

One common approach is to use synchronization mechanisms such as Mutex or RwLock.

Example 1#

For example, we can define the above global variable using Mutex as follows:

use std::sync::Mutex;

static GLOBAL_VAR: Mutex<i32> = Mutex::new(42);

In the above code, we use Mutex to synchronize the global variable. When using the global variable, we need to acquire the lock of the Mutex to ensure that only one thread can access the global variable at a time:

fn main() {
    let mut global_var = unsafe{GLOBAL_VAR.lock().unwrap()};
    *global_var = 43;
    println!("{}", *global_var);
}

In the above code, we use the lock() method to acquire the lock of the Mutex and modify the value of the global variable to 43, and finally print out the value of the global variable. It is important to note that acquiring the lock of the Mutex can fail, so we need to use the unwrap() method to handle possible errors.

Example 2#

use std::sync::Mutex;

static mut TABLE: Mutex<Table> = Mutex::new(Table::new());

type Table = Vec<Entry>;

#[derive(Debug)]
#[allow(dead_code)]
struct Entry {
    key: i32,
    value: i32,
}

fn main() {
    let mut table = unsafe { TABLE.lock().unwrap() };
    *table = vec![Entry { key: 1, value: 10 }];
    println!("table: {:?}", table);
}

The above code demonstrates how to define mutable global variables in Rust.

First, we use the use keyword to import std::sync::Mutex, which is a synchronization mechanism in Rust. Then, we use the static mut keyword to define a mutable global variable named TABLE with a type of Mutex<Table>. In Rust, using Mutex to protect the concurrency safety of shared data is a common approach.

In the main() function, we acquire the lock of TABLE and modify its value to a Vec containing an Entry. It is important to note that when using mutable global variables, the unsafe keyword must be used.

Finally, we print out the modified value of TABLE.

The use of global variables requires special attention to concurrency safety. Since global variables can be used from anywhere in the program, they can potentially cause issues such as data races. To address these issues, Rust provides some special mechanisms to ensure the safety of global variables, such as Mutex, RwLock, Atomic, and Channel, etc. When using global variables, we need to choose the appropriate synchronization mechanism based on the actual situation to ensure the concurrency safety of the program.

Conclusion#

In this article, we have introduced how to define and use global variables in Rust. Through global variables, we can share data in our programs, improving code reusability and maintainability. However, due to Rust's safety design, we need to pay special attention to the safety of global variables. We hope this article has been helpful in learning Rust.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.