Rustでもグローバル変数

これは、RICORA Advent Calendar 202221日目 の記事です。

昨日は、remetaさんの『またね、サンタさん / Goodbye, Santa』でした。

今日は、Rust 1.63から使えるようになった、constMutex::new() についてです。

これまでのグローバル変数

1.62以前のRustでは、lazy_staticonce_cell を利用して可変なグローバル変数を作っていました。

use once_cell::sync::Lazy;
static GLOBAL: Lazy<Mutex<Global>> = Lazy::new(|| Mutex::new({ ... }));

これからのグローバル変数

新しい書き方について知る前に、まずはRustのconst文脈について知る必要があります。

const 文脈とは

Rustの式・変数・定数には、コンパイル時に値が決定されなくてはならないものがいくつかあります。 具体的には以下に示した通りで、グローバル変数を実現するために必要な static 変数も該当します。

詳しくは、Constant Evaluation - The Rust Reference

const fn について

そのため、実行時に評価される通常の関数はグローバル変数の初期化には使えません。

そこで登場するのがconst文脈で呼び出せるconst fnです。 一定の制限をクリアすることでコンパイル時に実行してくれるため、const文脈でも使えるわけです。 コンパイル時に実行して困ることはあまりないため、標準ライブラリの関数たちも順次const fnに書き換えが進んでいるようです。

新しい Mutex::new()

そして、Rust 1.63から遂にMutex::new()const fnとなりました!

これによってstatic変数の初期化が可能になったため、以下のようにグローバル変数を簡単に、かつ安全に書くことができるようになったわけです。

static GLOBAL: Mutex<Global> = Mutex::new( ... );

終わりに

一瞬で3年生も終わりとなり、もうOBと呼ばれる学年になったことに戦慄しています。 学年間の垣根が非常に低いRICORAですが、かと言ってうざったい先輩にならないように気をつけていきます。

明日はunagi_dogさんの『OAuth2.0まとめ』が予定されていますのでお楽しみに!

2022-12-22追記
『OAuth2.0まとめ』は24日に引っ越しになり、同じくunagi_dogさんの『ふりかえり2022』が公開されていますので是非ご覧ください!(サイトのデザインを褒めてくれてありがとう)