Programming自動化、組み込みおよびシステム開発者

Rustにおける定数式(const expressions)の動作、計算されるタイミング、コンパイラがコンパイル時に値を計算する実践的な使用例について説明してください。

Hintsage AIアシスタントで面接を突破

回答

Rustでは、定数式(const)はコンパイル時に計算されるため、プログラムが実行される前に値を生成できます。このような式は、配列のサイズ、静的構造における値、ジェネリクスのパラメータなど、不変の定数に対して厳密に知られている値が必要な他の状況に使用されます。

Rustでは、他の const 表現の中で使用されたり、定数変数の初期化のために利用される「定数」関数(const fn)を作成できます。コンパイラは、このような表現が無効な操作(例えばメモリへのアクセス)を含まないことを保証します。

例:

const fn fib(n: u32) -> u32 { match n { 0 | 1 => 1, _ => fib(n - 1) + fib(n - 2), } } const F8: u32 = fib(8); const ARR: [u32; F8 as usize] = [0; F8 as usize]; // サイズ34の配列

この例では、F8の値と配列ARRのサイズはコンパイル時に計算されます。

裏の質問

const関数と通常の関数の違いは何で、どんな関数でもconst fnとして宣言できますか?

回答: いいえ、すべての関数をconst fnとして宣言することはできません。const fnは副作用を伴わない、または安全でないメモリ操作を含むことができる許可された操作のみを含むことができます。例えば、const fn内でファイルを開いたり、動的にメモリを割り当てたりすることはできません。

const fn add(x: i32, y: i32) -> i32 { x + y // 許可されている } // これはコンパイルできません: const fn fail() -> String { // エラー! String::from("err") }

このテーマの詳細を知らないことによる実際のエラーの例


物語

あるプロジェクトで、定数関数を介してコンパイル時に文字列のハッシュ値を計算しようとしましたが、HashMapの標準メソッドとメモリの割り当てをその関数内で使用しました。プログラムはコンパイルされず、const fn内での操作の不正について不明なエラーが出力されました。


物語

大規模な組み込み開発で、開発者はコンパイル時に計算が必要なフィールドを持つ定数構造体を定義しましたが、他のクレートからの関数を使用し、const fnとしてマークされていませんでした。これにより、静的バッファのサイズを決定するためにこのロジックを使用することができなくなりました。


物語

コード内で、staticconstの違いを混同し、「定数」を実行時に変更しようとしたため、暗黙のUB(未定義の動作)を受けることになりました。Rustの定数は値としてメモリに配置されるのではなく、使用場所でコンパイラによって置き換えられるため、変更することは全く想定されていません。