简体   繁体   English

Rust中的参考

[英]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. 因为aElement类型的,而不是&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? 为什么分别在调用doublemut_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, if object 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 * so object 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM