トレイトの実装対象が参照型の場合について。
代表例は impl MyTrait for &MyType
のようなコード。
注: コード内に参照型がなくても、型パラメタがあるとこのパターンになりうる。
self
引数により参照を消費する (参照の影響もなくなる)。
なお、この用法は後述のサンプルにて紹介する Iterator
トレイトの count
メソッドなどで見られる。このメソッドは要素数の確認のために、要素がつきるまでイテレータを走査する。そのため、値であれ参照であれ、以降はイテレータへのアクセスを提供するものは役に立たなくなるため、使用を禁止したほうがよい。
メソッド呼出形式においては、参照型への実装のみで値型も自動サポートされる。
これは自動参照があるためで、&self
を使った場合の自動逆参照と似ている。
なお、必要になる事は少なそうだが、参照版と値版とで実装を二つ用意してもよい。
以下では、末尾の実装の &
の箇所が重要。
fn main() {
let r = &MyType {};
r.with_self_value();
}
trait MyTrait {
fn with_self_value(self) where Self: Sized {}
}
struct MyType {}
impl MyTrait for &MyType {}
以下では、型パラメタ T
が参照型も含んでいる。
fn main() {
let r = &MyType {};
r.with_self_value();
}
trait MyTrait {
fn with_self_value(self) where Self: Sized {}
}
struct MyType {}
impl<T> MyTrait for T {}
Iterator
の一部メソッドなどに利用例がある。
fn count(self) -> usize where Self: Sized
以下は Iterator
の参照に対する実装。
impl<I: Iterator + ?Sized> Iterator for &mut I
そのため、以下のようなコードが可能。
fn main() {
let vec = vec![1, 2, 3];
let iter = &mut vec.iter();
assert_eq!(iter.count(), 3);
}