UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Rust】const と let の違い

Exercismの問題を解いていて、letconstの違いがわからなかったので調べた

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ではconstletの役割が違うみたい

const と let

const

Rustのconstコンパイル時に評価できる以下の場合に利用する

  • 定数を宣言する場合:const FOO: usize = 3;
  • コンパイル時に評価可能な関数を宣言する場合:const fn foo() -> &'static str

関数呼び出しの結果や実行時にのみ決定できるものには設定できない

constは型を明示する必要があり、大文字が望ましい

let

letは実行時の計算値の変数宣言に利用するが、再代入はできない

再代入したいものには、let mutを明示的に使う必要がある