介绍#
Rust は安全で効率的なシステムプログラミング言語です。その文法は C 言語に似ていますが、安全性と並行性の面で優れています。Rust では、グローバル変数の定義と使用により、データの共有、コードの再利用性と保守性の向上が可能です。この記事では、Rust でのグローバル変数の定義と使用方法について説明します。
グローバル変数の定義#
Rust では、グローバル変数を定義するにはstaticキーワードを使用します。グローバル変数の定義方法は 2 つあります:
不変なグローバル変数の定義#
static GLOBAL_VAR: i32 = 42;
上記のコードでは、GLOBAL_VARという名前のグローバル変数を定義し、型はi32で初期値は42です。注意点として、定義するグローバル変数には型を指定する必要があります。不変なグローバル変数を定義した後は、プログラムのどこからでもその値を読み取ることができます。
変更可能なグローバル変数の定義#
static mut GLOBAL_VAR: i32 = 42;
上記のコードでは、static mutを使用してGLOBAL_VARという名前の変更可能なグローバル変数を定義し、型はi32で初期値は42です。注意点として、変更可能なグローバル変数を定義するにはmutキーワードを使用し、変更可能なグローバル変数を使用する際にはunsafeキーワードを使用する必要があります。
グローバル変数の使用#
Rust では、グローバル変数を使用するには完全修飾パスを使用する必要があります。例えば、上記で定義したグローバル変数GLOBAL_VARの値をプログラムのどこからでも使用することができます:
fn main() {
println!("{}", GLOBAL_VAR);
}
上記のコードでは、完全修飾パスを使用してグローバル変数GLOBAL_VARの値にアクセスし、それをコンソールに出力しています。
グローバル変数の安全性#
Rust では、グローバル変数の使用には並行性の問題など特別な注意が必要です。グローバル変数はプログラムのどこからでも使用できるため、データ競合などの問題が発生する可能性があります。これらの問題を解決するために、Rust はグローバル変数の安全性を確保するための特別なメカニズムを提供しています。
一般的な方法の 1 つは、MutexやRwLockなどの同期メカニズムを使用することです。
サンプル 1#
例えば、上記のグローバル変数の定義を以下のように変更できます:
use std::sync::Mutex;
static GLOBAL_VAR: Mutex<i32> = Mutex::new(42);
上記のコードでは、Mutexを使用してグローバル変数を同期化しています。グローバル変数を使用する際には、Mutexのロックを取得する必要があります。これにより、同時にアクセスできるスレッドが 1 つだけになることが保証されます:
fn main() {
let mut global_var = unsafe{GLOBAL_VAR.lock().unwrap()};
*global_var = 43;
println!("{}", *global_var);
}
上記のコードでは、lock()メソッドを使用してMutexのロックを取得し、グローバル変数の値を43に変更し、最後にグローバル変数の値を出力しています。注意点として、Mutexのロックを取得する際には失敗する可能性があるため、unwrap()メソッドを使用して可能なエラーを処理する必要があります。
サンプル 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() };
// let mut entry = Entry { key: 1, value: 10 };
*table = vec![Entry { key: 1, value: 10 }];
println!("table: {:?}", table);
}
上記のコードは、Rust で可変のグローバル変数を定義する方法を示しています。
まず、useキーワードを使用してstd::sync::Mutexをインポートしています。これは、Rust で共有データの並行安全性を保護するための同期メカニズムです。次に、static mutキーワードを使用してTABLEという名前の可変のグローバル変数を定義し、型はMutex<Table>です。Rust では、可変のグローバル変数を使用する際にはunsafeキーワードを使用する必要があります。
main()関数では、TABLEのロックを取得し、その値を 1 つのEntryを含むVecに変更しています。可変のグローバル変数を使用する際には、unsafeキーワードを使用する必要があります。
最後に、変更後のTABLEの値を出力しています。
グローバル変数の使用には特に並行性の問題に注意する必要があります。グローバル変数はプログラムのどこからでも使用できるため、データ競合などの問題が発生する可能性があります。これらの問題を解決するために、Rust はMutex、RwLock、Atomic、Channelなどの特別なメカニズムを提供しています。グローバル変数を使用する際には、適切な同期メカニズムを選択してプログラムの並行性を確保する必要があります。
結論#
本記事では、Rust でのグローバル変数の定義と使用方法について説明しました。グローバル変数を使用することで、データの共有、コードの再利用性、保守性の向上が可能です。また、Rust の安全性の設計により、グローバル変数の安全性に特に注意する必要があります。本記事が Rust の学習に役立つことを願っています。