函数调用中的自动借用

Automatic Borrowing in Function Calls

我是 Rust 的新手,我对借用其参数的函数有疑问。

在 C++ 中,函数的类型签名单独指定是否通过引用获取参数;调用该函数的代码不需要明确指示它正在传递引用。例如:

// The function signature indicates x should be passed by reference.
void increment(int& x) {
    ++x;
}
void main() {
    int y = 0;
    increment(y); // y is implicitly passed by reference
    // y is now 1
}

另一方面,Rust 似乎不允许这样做。以下代码将无法编译:

fn output(x: &isize) {
    println!("{}", x);
}

fn main() {
    let y: isize = 0;
    output(y); // Error.
    // output(&y); <- this is ok though
}

当通过使用方法语法时,如果函数签名采用 &self&mut self,则这些借用发生在调用者不使用 &&mut.

一般函数参数不会自动借用是否有原因?如果是,为什么在使用方法语法时会发生?

虽然也用 & 编写并且经常称为 "references",但 Rust 中的这些类型在 C++ 中是 pointers。它们是 first-class 值,与 C++ 引用不同,因此可以(并且通常必须)显式创建和取消引用。

访问字段和方法是一种非常常见的操作,但是,通常您拥有 &self/&mut self 方法但拥有对象而不是仅仅拥有对它的引用或对您需要访问其字段的结构。在那些情况下要求显式创建引用并取消引用它们会导致大量线路噪音(特别是因为运算符优先级因此您必须键入 (&foo).method()(*foo).field)而基本上没有任何好处:引用是免费的,即使在简陋的 C 语言 (foo->field) 中,取消引用访问也被认为是值得的捷径。因此,在必要时,字段访问自动取消引用(顺便说一下,包括智能指针)和方法调用 "auto-references".

在其他地方(例如参数传递),这不是很常见,而且明确性有时对 reader 很有价值。一般来说,编译器无法理解你的意思。最近添加的 "deref coercions" 加剧了这种情况,例如,x: Rc<T>&x 可能导致 &T 而不是 &Rc<T>。也有用于自动取消引用的决胜局,但它们非常清楚,通常是您想要的。

据我了解,自动借位是符合人体工学的设计

struct U;
impl U {
  fn test(&self) {}
}
fn main() {
  let u = U;
  u.test(); // with auto borrow
  (&u).test(); // if without auto borrow , you have to write code like this
}