1. ホーム
  2. reference

構造体への参照に対するAdd traitを実装するにはどうすればよいですか?

2023-10-07 07:24:57

質問

私は、2つの要素 Vector 構造体を作成し + 演算子をオーバーロードしたい。

私はすべての関数とメソッドが値ではなく参照を取るようにしました。 + 演算子も同じように動作するようにしたいです。

impl Add for Vector {
    fn add(&self, other: &Vector) -> Vector {
        Vector {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

どのバリエーションを試すかによって、寿命の問題や型の不一致が発生します。具体的には &self 引数は正しい型として扱われないようです。

にテンプレート引数がある例を見たことがあります。 impl と同様に Add と同じですが、異なるエラーになります。

私が見つけたのは どのように演算子は異なるRHS型と戻り値のためにオーバーロードされることができますか? とあるが、答えの中のコードは use std::ops::Mul; を先頭に置いても動作しません。

rustc 1.0.0-nightly (ed530d7a3 2015-01-16 22:41:16 +0000) を使用しています。

私は "あなたは2つのフィールドしか持っていない、なぜ参照を使用する" を答えとして認めません。私が100要素の構造体を望んでいたらどうしますか? もしそうであれば、大きな構造体でも値で渡すべきであることを実証する回答を受け入れます (私はそうではないと思いますが。) 構造体のサイズと値で渡すことと構造体について良い経験則を知ることに興味がありますが、それは現在の質問ではありません。

どのように解決するのですか?

を実装する必要があります。 Add を実装する必要があります。 &Vector よりも Vector .

impl<'a, 'b> Add<&'b Vector> for &'a Vector {
    type Output = Vector;

    fn add(self, other: &'b Vector) -> Vector {
        Vector {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

その定義に Add::add は常に self を値で取ります。しかし、参照は他の型と同様に 1 であるため、trait を実装することもできます。参照型に trait が実装されている場合,その型は self は参照であり、参照は値で渡されます。通常、Rustでは値で渡すと所有権が移ることになりますが、参照が値で渡される場合は、単にコピーされるだけで、(mutableな参照なら再借り入れや移動も)参照先の所有権は移りません(そもそも参照は参照先を所有しないので)。このようなことを考慮すると Add::add (そして他の多くの演算子) が self を値で指定します。オペランドの所有権を取得する必要がある場合は、実装として Add を構造体/列挙体に対して直接実装し、そうでない場合は Add を実装することができます。

ここで self&'a Vector を実装しているからです。 Add を実装しているからです。

も指定していることに注意してください。 RHS 型パラメータも別の寿命で指定し、2つの入力パラメータの寿命が無関係であることを強調していることに注意してください。


1 実は参照型は特殊で、自分のクレートで定義された型への参照に対するtraitを実装することができます(つまり、例えば T に対して実装することが許されているならば、それを &T ). &mut TBox<T> は同じ振る舞いをしますが、一般的にそれは U<T> では U が同じクレートで定義されていない場合。