このケースでは通貨単位を型として表現している // Money<T> のT で通貨単位を表すようにする // ここで嬉しいのは、誤った通貨単位同⼠の加算をコンパイル時に検査できること // T はただのラベルとして扱いたいだけだが消費しないと怒られるので、std::marker::PhantomData を⽤いる // 参考: https://keens.github.io/blog/2018/12/15/rustdetsuyomenikatawotsukerupart_1__new_type_pattern/ #[derive(Clone, Debug, PartialEq, Eq)] pub struct Money<T> { amount: Decimal, currency: PhantomData<T>, } impl<T> Money<T> { fn new(amount: Decimal) -> Self { Self { amount, currency: PhantomData::<T>, } } } impl<T> Add for Money<T> { type Output = Money<T>; fn add(self, other: Money<T>) -> Self::Output { Self::new(self.amount + other.amount) } } #[derive(Clone, Debug, PartialEq, Eq)] pub enum JPY {} #[derive(Clone, Debug, PartialEq, Eq)] pub enum USD {}