[英]References in Rust
I try to understand the borrow mechanism and references in Rust, and for this reason I created the following small example: 我试图了解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])
}
So, the above code works, but my confusion comes when calling the double
method. 因此,上面的代码有效,但是当调用double
方法时,我感到困惑。 As you can see it is defined as fn double(&self) -> Element
, so it basically takes an immutable reference. 如您所见,它被定义为fn double(&self) -> Element
,因此它基本上采用了不可变的引用。 Now in the main, I create a new Element
variable called a
, and then call double
method on it twice. 现在,在主体中,我创建了一个称为a
的新Element
变量,然后对其两次调用double
方法。 First time I just do a.double()
, second time (&a).double()
. 第一次我只是做a.double()
,第二次是(&a).double()
。 Both of them seem to work correctly, but I do not understand why the first call a.double()
is a valid and compiler doesn't complain about it. 它们似乎都可以正常工作,但是我不明白为什么第一次调用a.double()
是有效的,而编译器没有抱怨它。 Since a
is of type Element
, not of type &Element
, and clearly the double
method asks for &Element
, so about a reference. 因为a
是Element
类型的,而不是&Element
类型的,并且显然double
方法要求&Element
,所以关于引用。 Same thing also happens with the mut_double
method. mut_double
方法也会发生相同的情况。 Why do I not have to specify (&a)
or (&mut a)
when calling the double
and mut_double
methods, respectively? 为什么分别在调用double
和mut_double
方法时不必指定(&a)
或(&mut a)
? What is happening under the hood with Rust? Rust在幕后发生了什么?
Short: the language works like that because it's a lot more convenient. 简短:语言的工作原理是这样,因为它更加方便。
Long ( extract from the book , emphasis is mine): 长( 从书中摘录 , 重点是我的):
Where's the
->
Operator?->
运算符在哪里?In languages like C++, two different operators are used for calling methods: you use
.
在C ++之类的语言中,两个不同的运算符用于调用方法:use.
if you're calling a method on the object directly and->
if you're calling the method on a pointer to the object and need to dereference the pointer first. 如果要直接在对象上调用方法,则->
如果要在指向对象的指针上调用方法,并且需要先取消引用该指针。 In other words, ifobject
is a pointer,object->something()
is similar to(*object).something()
. 换句话说,如果object
是指针,则object->something()
与(*object).something()
相似。Rust doesn't have an equivalent to the
->
operator; Rust没有等效于->
运算符; instead, Rust has a feature called automatic referencing and dereferencing . 相反,Rust具有称为自动引用和取消引用的功能 。 Calling methods is one of the few places in Rust that has this behavior. 调用方法是Rust少数具有这种行为的地方之一。Here's how it works: when you call a method with
object.something()
, Rust automatically adds in&
,&mut
, or*
soobject
matches the signature of the method. 它是这样工作的:当您使用object.something()
调用方法时, Rust自动添加&
,&mut
或*
从而使object
与方法的签名匹配。 In other words, the following are the same: 换句话说,以下是相同的:p1.distance(&p2); (&p1).distance(&p2);
The first one looks much cleaner. 第一个看起来更干净。 This automatic referencing behavior works because methods have a clear receiver—the type of
self
. 这种自动引用行为之所以有效,是因为方法具有明确的接收者(self
的类型)。 Given the receiver and name of a method, Rust can figure out definitively whether the method is reading (&self
), mutating (&mut self
), or consuming (self
). 给定方法的接收者和名称,Rust可以明确确定该方法是读取(&self
),变异(&mut self
)还是使用(self
)。 The fact that Rust makes borrowing implicit for method receivers is a big part of making ownership ergonomic in practice. 在实践中,Rust使借方隐含于方法接收者这一事实是使所有权符合人体工程学的重要组成部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.