Exercismの問題を解いていて、let
とconst
の違いがわからなかったので調べた
Exercismの問題は半構造化データされたログメッセージを生成するというもの
次のようなEnumを用意しておいて
#[derive(Clone, PartialEq, Debug)] pub enum LogLevel { Info, Warning, Error, }
次のようにログメッセージを出力することが目標で、ログレベルに対応する関数を実装する
"[<LEVEL>]: <MESSAGE>"
たとえば、出漁結果が以下のようになるようにする
log(LogLevel::Error, "Stack overflow") // Returns: "[ERROR]: Stack overflow"
このとき、以下のような実装をしたのだが、
pub fn log(level: LogLevel, message: &str) -> String { const LEVEL: String = format!("{:?}", level); format!("[{}]: {}", LEVEL.to_uppercase(), message) }
次のようなエラーが発生した
error[E0435]: attempt to use a non-constant value in a constant --> src/lib.rs:14:43 | 14 | const LEVEL: String = format!("{:?}", level); | ----------- ^^^^^ non-constant value | | | help: consider using `let` instead of `const`: `let LEVEL`
JavaScriptのノリで再代入しないのでconst
を使ったが、Rustではconst
とlet
の役割が違うみたい
const と let
const
Rustのconst
はコンパイル時に評価できる以下の場合に利用する
- 定数を宣言する場合:
const FOO: usize = 3;
- コンパイル時に評価可能な関数を宣言する場合:
const fn foo() -> &'static str
関数呼び出しの結果や実行時にのみ決定できるものには設定できない
const
は型を明示する必要があり、大文字が望ましい
let
let
は実行時の計算値の変数宣言に利用するが、再代入はできない
再代入したいものには、let mut
を明示的に使う必要がある