演算子
演算子オーバーロードは std::ops のトレイトを通じて実装されます。
// Copyright 2023 Google LLC // SPDX-License-Identifier: Apache-2.0 #[derive(Debug, Copy, Clone)] struct Point { x: i32, y: i32, } impl std::ops::Add for Point { type Output = Self; fn add(self, other: Self) -> Self { Self { x: self.x + other.x, y: self.y + other.y } } } fn main() { let p1 = Point { x: 10, y: 20 }; let p2 = Point { x: 100, y: 200 }; println!("{p1:?} + {p2:?} = {:?}", p1 + p2); }
議論のポイント:
&Pointに対してAddを実装することもできます。これはどのような状況で役立つでしょうか?- 回答:
Add:addはselfを消費します。演算子をオーバーロードする対象の型TがCopyでない場合は、&Tに対しても演算子をオーバーロードすることを検討すべきです。これにより、呼び出し側で不要なクローンを避けられます。
- 回答:
Outputが関連型なのはなぜでしょうか? これをメソッドの型パラメータにすることはできるでしょうか?- 短い答え: 関数の型パラメータは呼び出し側が制御しますが、関連型(
Outputのようなもの)はトレイトの実装者が制御します。
- 短い答え: 関数の型パラメータは呼び出し側が制御しますが、関連型(
- 2 つの異なる型に対して
Addを実装することもできます。たとえば、impl Add<(i32, i32)> for PointはタプルをPointに加算します。
Not トレイト(! 演算子)は、C 系言語の同じ演算子のように引数を bool に変換しないため、注目に値します。代わりに、整数型に対しては数値の各ビットを反転します。これは算術的には、引数を -1 から減算することと等価です: !5 == -6。