サンプルコードで身につける: 演算子オーバーロード — Add トレイト
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1Money + Money — 最小の Add 実装
impl Add for Money の add メソッドに「足す」の意味を書くと、Money 同士を + で足せるようになります。type Output = Money は + の結果の型の宣言です。金額のように足し算が自然な意味を持つ型では、メソッド呼び出しより式のほうが読みやすくなります。
2Add と Sub をそろえる
+ と - はそれぞれ独立したトレイト(Add と Sub)なので、使いたい演算子ごとに実装します。座標型に両方をそろえると、移動や差分の計算が数式のままの形で書けます。std::ops には Mul や Neg など、他の演算子に対応するトレイトも同じ形で揃っています。
3右辺の型を変える — Add<i32>
Add<i32> のように型パラメータを指定すると、「Money + i32」という左右で型が違う足し算を定義できます。何も指定しない impl Add は「同じ型同士の足し算」の省略形だった、という関係です。金額に手数料の数値を直接足すような、単位が文脈から明らかな場面で便利です。
4Copy と組み合わせて使い回す
add は self を値で受け取るため、そのままでは + を使うたびに両辺がムーブされます。#[derive(Clone, Copy)] を付ければ複製が渡されるようになり、ループの中で pos = pos + m と繰り返し足せます。小さな数値だけでできた型に Copy を付けるのは、演算子オーバーロードの定番の組み合わせです。
5ベクトル演算 — pos + velocity * dt
Add(ベクトル同士の加算)と Mul<f64>(スカラー倍)をそろえると、物理シミュレーションの位置更新が数式とほぼ同じ形で書けます。式全体の意図が一目で伝わるのが、ゲームやグラフィックスのコードでベクトル型に演算子を実装する理由です。直感に合う演算だけに使う、という鉄則はここでも同じです。