Rustにおける定数評価は、一部の計算や初期化をプログラムの実行時ではなくコンパイル時に実行することを可能にします。
const PI: f64 = 3.1415;
static mut GLOBAL_COUNTER: i32 = 0;
const fnは、結果がconstやstaticの値を設定するために使用できる関数です。このような関数は定数コンテキストで呼び出すことができます。
const fn factorial(n: usize) -> usize { if n == 0 { 1 } else { n * factorial(n - 1) } } const FACT_5: usize = factorial(5); // コンパイルされます!
const fnの制限:
Box::newなど)を使用できません,質問: 結果が変更されない場合、任意の関数をconstコンテキストで使用できますか?例えば、次のように:
fn add(a: i32, b: i32) -> i32 { a + b } const RES: i32 = add(1, 2);
典型的な誤った回答: はい、関数は純粋であり結果は事前に知られています。
正しい回答: いいえ、関数は明示的にconst fnとして宣言される必要があります。そうでなければ、const初期化内で呼び出すことはできません。通常の関数は実行時のみ呼び出されます!
例:
const fn add(a: i32, b: i32) -> i32 { a + b } const RES: i32 = add(1, 2); // コンパイルされます!
物語
三次元ジオメトリの計算を行うプロジェクトで、開発者は通常の関数を使用して値のテーブルを宣言しようとしましたが、const fnではありませんでした。その結果、コンパイルエラーが発生し、コンパイル時計算から得られる利益が失われました。
物語
グローバルキャッシュにstatic mutを使用した結果、複数のスレッドからのアクセスでデータ競合が発生しました(static mutは安全ではありません!)。グローバルリソースへのアクセスを同期するためにAtomicやMutexを使用する必要がありました。
物語
大きな配列の初期化を高速化するためにstaticとして定義しましたが、staticは常に固定アドレスを持つため、データがローカルとしてCPUキャッシュに入らず、サーバーロジックのホットパスで操作が遅くなりました。ランタイムで計算を行うローカルlet式を使用する必要がありました。