rs.nkmk.me

Rustのdbg!マクロの使い方

Posted: | Tags: Rust, マクロ

Rustでデバッグのために変数の値などを確認したい場合はdbg!マクロが便利。

デバッグ用にはprintln!よりもdbg!

簡単なデバッグのために変数の値を確認したい場合、println!マクロよりもdbg!マクロのほうが簡単。""{}が不要。

let a = 100;

println!("{a}");
// 100

dbg!(a);
// [src/bin/dbg.rs:7] a = 100
source: dbg.rs

注意点1: dbg!は所有権を奪う

println!と異なり、dbg!は所有権を奪う。

上の例の整数値のようにコピーできる型(Copyトレイトが実装されている型)の場合は問題ないが、コピーできない型の場合は要注意。

let s = String::from("abc");

dbg!(s);
// [src/bin/dbg.rs:12] s = "abc"

// let x = s.len();
// error[E0382]: borrow of moved value: `s`
source: dbg.rs

&を付けて参照を渡せばよい。

let s = String::from("abc");

dbg!(&s);
// [src/bin/dbg.rs:20] &s = "abc"

let x = s.len();
assert_eq!(x, 3);
source: dbg.rs

注意点2: dbg!は標準エラー出力

println!は出力先が標準出力(stdout)だが、dbg!は標準エラー出力(stderr)。

単に表示するだけなら特に気にする必要はないが、リダイレクトなどで処理する場合は要注意。

ちなみにprintln!, print!の標準エラー出力版のeprintln!, eprint!もある。

dbg!は式を評価し、その値を返す

dbg!は引数に指定された式を評価し、その値を返す。dbg!を式の途中に組み込んでその評価値を確認することが可能。

以下は公式リファレンスに示されている例。

let a = 2;
let b = dbg!(a * 2) + 1;
// [src/bin/dbg.rs:28] a * 2 = 4

assert_eq!(b, 5);
source: dbg.rs

階乗を再帰的に求める例。コードの各地点でどういう値になっているか確認できる。

fn factorial(n: u32) -> u32 {
    if dbg!(n <= 1) {
        dbg!(1)
    } else {
        dbg!(n * factorial(n - 1))
    }
}

dbg!(factorial(4));
// [src/bin/dbg.rs:34] n <= 1 = false
// [src/bin/dbg.rs:34] n <= 1 = false
// [src/bin/dbg.rs:34] n <= 1 = false
// [src/bin/dbg.rs:34] n <= 1 = true
// [src/bin/dbg.rs:35] 1 = 1
// [src/bin/dbg.rs:37] n * factorial(n - 1) = 2
// [src/bin/dbg.rs:37] n * factorial(n - 1) = 6
// [src/bin/dbg.rs:37] n * factorial(n - 1) = 24
// [src/bin/dbg.rs:41] factorial(4) = 24
source: dbg.rs

関連カテゴリー

関連記事