我尝试理解Rust中的借用机制和引用,因此我创建了以下小例子:
extern crate core;
use core::fmt::Debug;
#[derive(Copy, Clone)]
pub struct Element(pub (crate) [u8; 5]);
impl Debug for Element {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "Element({:?})", &self.0[..])
}
}
impl Element {
fn one() -> Element {
Element([1, 1, 1, 1, 1])
}
fn double(&self) -> Element {
let mut result = *self;
for i in 0..5 { result.0[i] = 2*result.0[i]; }
result
}
fn mut_double(&mut self) -> Element {
for i in 0..5 { self.0[i] = 2*self.0[i]; }
*self
}
}
fn main() {
let mut a = Element::one();
println!("a = {:?}", a); // a = Element([1, 1, 1, 1, 1])
a = a.double();
println!("a = {:?}", a); // a = Element([2, 2, 2, 2, 2])
a = (&a).double();
println!("a = {:?}", a); // a = Element([4, 4, 4, 4, 4])
a = a.mut_double();
println!("a = {:?}", a); // a = Element([8, 8, 8, 8, 8])
a = (&mut a).mut_double();
println!("a = {:?}", a); // a = Element([16, 16, 16, 16, 16])
}
所以,上面的代码可以工作,但是在调用 double
方法时我会感到困惑 . 如您所见,它被定义为 fn double(&self) -> Element
,因此它基本上采用不可变引用 . 现在在main中,我创建一个名为 a
的新 Element
变量,然后在其上调用 double
方法两次 . 我第一次做 a.double()
,第二次 (&a).double()
. 它们似乎都正常工作,但我不明白为什么第一次调用 a.double()
是有效的,编译器不会抱怨它 . 由于 a
的类型为 Element
,而不是类型 &Element
,显然 double
方法要求 &Element
,所以关于引用 . mut_double
方法也会发生同样的事情 . 为什么在分别调用 double
和 mut_double
方法时不必指定 (&a)
或 (&mut a)
?在Rust的引擎盖下发生了什么?
1 回答
简短:语言就是这样,因为它更方便 .
很长(extract from the book, emphasis 是我的):