Rust言語でMatrix型と和を実装する
概要
Rust言語を勉強するにあたり,Rustのジェネリクスなどを体感するために複素数や行列演算を定義してみようと思った。
(本記事のコードはかなりChatGPTで生成されたコードを参考にしています。)
対象読者
Rust言語に興味があり,利用しはじめたくらいの方
コード
本記事で紹介したコードは以下にまとめています。
ジェネリクスによるMatrix型の定義
まずはRustのstruct
を使ってMatrix
構造体を定義する。
行列の構造体なので,シンプルに二次元配列形式のdata
だけ持っている。
ここで,型T
の配列をROWS
×COLS
の行列で初期化できるようにパラメータを指定している。
Matrix<T, const ROWS: usize, const COLS: usize>
Rust言語では型パラメータT
だけでなく,usize
型の値などもパラメータとして指定することができるので,実装がシンプルになる。
#[derive(Debug, Clone)]
pub struct Matrix<T, const ROWS: usize, const COLS: usize> {
pub data: [[T; COLS]; ROWS],
}
演算
Addの実装
演算子の実装はstd::ops::Add
などのトレイトを実装することで実現できる。
以下が行列の和の実装。
impl<T: Add<Output = T> + Default + Copy, const ROWS: usize, const COLS: usize> Add for Matrix<T, ROWS, COLS> {
type Output = Self;
fn add(self, other: Self) -> Self {
let mut result = Self::new();
for i in 0..ROWS {
for j in 0..COLS {
result.data[i][j] = self.data[i][j] + other.data[i][j];
}
}
result
}
}
Rust言語を触り始めて私が戸惑った部分はここ。
<T: Add<Output = T> + Default + Copy, const ROWS: usize, const COLS: usize>
これは,「トレイト境界を設ける」などと解説されている部分で,ジェネリクスのパラメータT
などに制約を与えている。
Add<Output = T> + Default + Copy
のように+
で制約を追加しているイメージだ。
ここでのT
の制約は,型T
同士の和の出力の型がT
であるようなAdd
トレイトが実装されており,Defaultトレイトが実装されており,Copyトレイトが実装されているという制約だ。
上記を満たすTについて,MatrixのAddを実装するということになる。
※Defaultトレイトは,型Tのゼロを返す関数が実装されている。(f32なら0.0, usizeなら0のように)
和の実装自体は,Addトレイトのadd関数で,行列の各要素の和を格納した新たなMatrixをreturnする関数を実装するだけで難しいポイントはなさそう。
制約さえ慣れてしまえば,自由自在に実装できそうだ。
Discussion