「C言語」頭の老人には毎度恐れいるばかりのRustであります。今回はstaticとな。C言語であればスコープにかかわりなく静的に「持続する」変数を使うことができるアレです。Rustにもstaticあり。似たものに見えて、そのように使えないこともないのですが、制限キビシーです。unsafeの嵐。やってはいけないってこと?
※「やっつけな日常」投稿順 Index はこちら
いつもお世話になっております「Rust By Example 日本語版」様の以下のページを読んでおりましたら「Rustには2種類の定数あり」と。
その心は
-
- const
- static
の2つだそうです。const が定数であることに異を唱える気は毛頭ありませぬが、staticも「定数」なの? staticっていうのはライフタイム的な、変数の存続期間じゃないの?と。。。 1か所引用させていただきましょう。
The static lifetime is inferred and does not have to be specified. Accessing or modifying a mutable static variable is unsafe.
mutableなstatic variableの変更はunsafeだと。ひっくり返せばC言語同様に変更できるってことじゃないの? でも、やってみて思い知ったです。
今回実験のソース
今回は、Cでいう大域変数のstatic と ローカル変数のstaticの両方を作ってみました。まず「変数」と思って小文字で「変数名」を書くだけで、RUSTコンパイラからお叱りをうけます。大文字で始めろと。たしかに名前でみても完全「定数扱い」されてますなあ。
Cではフツーな感じで書いてしまうとコンパイルエラー出まくります。staticな定数に mut なんて宣言すんじゃねえよ、という圧力をひしひしと感じます。めげずに、エラー箇所を必殺の unsafeで囲んでいきました。
unsafe { }
出来上がった実験コードが以下に
static mut GS000: i32 = 100; fn func000() -> i32 { unsafe { GS000 += 1; return GS000; } } fn func001() -> i32 { static mut SS1: i32 = 0; unsafe { SS1 += 1; return SS1; } } fn main() { unsafe { println!("GS000: {}", GS000); } println!("func000: {}", func000()); unsafe { println!("GS000: {}", GS000); } println!("func000: {}", func000()); println!("func001: {}", func001()); println!("func001: {}", func001()); println!("func001: {}", func001()); }
短いコードですが、unsafeだらけで汚いです。とほほ。
実行結果
走らせた結果が以下に。
一応、C言語的な動作をさせることはできましたが、汚い、圧倒的に汚い。もっと他に方法があるはず。またそのうち。