以下のようなtraitがあったとき、
trait
trait BarTrait {
fn bar(self, x: i32);
}
以下のように、self
や他の引数にmut
を付けてもimplできる(問題なくコンパイル可能)
impl
struct Foo {
x: i32,
}
impl BarTrait for Foo {
// selfとxに、それぞれBarTraitの定義にはなかったmutが付いている
fn bar(mut self, mut x: i32) {
self.x += 1;
x += 1;
println!("bar for foo: {} {}", self.x, x);
}
}
mutの有無は関数内部の実装の問題で、外から見たIFには影響しない。
(C++でも、メソッドの宣言と定義で値引数のconst
の有無が異なったり、override時に値引数のconst
の有無が異なっても問題ない(ポインタ引数での向き先のconst
の有無に関してはもちろん駄目))
さらに、以下のようにmut
付きで定義したメソッドのドキュメントでは、自動的にmut
が省かれる:
impl Foo {
/// foo
pub fn foo(mut self, mut x: i32) {
self.x = 0;
x = 1;
println!("{} {}", self.x, x);
}
}
ドキュメントを生成
cargo doc
![]() |
---|
↑生成されたドキュメント。selfとxにmutが付いていない。
補足
実際、たとえmut
を付けずに実装しても、以下のようにすればいくらでも後からmut
に変更可能。
fn bar(self, x: i32) {
let mut mself = self;
let mut x = x;
...
引数のmut
の有無に本質的な違いはないことが分かる。
(もちろん、&self
と&mut self
だとこうはいかない)