【问题标题】:Automatic Borrowing in Function Calls函数调用中的自动借用
【发布时间】:2015-05-19 21:18:13
【问题描述】:

我是 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
}

通过使用方法语法时,如果函数签名采用&amp;self&amp;mut self,则这些借用发生在调用者不使用&amp;&amp;mut 的情况下。

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

【问题讨论】:

    标签: rust


    【解决方案1】:

    虽然也使用&amp; 编写并经常被称为“引用”,但在 Rust 中,这些类型在 C++ 用语中是指针。它们是一等值,与 C++ 引用不同,因此可以(并且通常必须)显式创建和取消引用。

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

    在其他地方(例如参数传递),这种情况很少需要,而且明确性有时对读者很有价值。通常,编译器无法弄清楚您的意思。最近添加的“deref coercions”加剧了这种情况,例如,&amp;x for x: Rc&lt;T&gt; 可能导致&amp;T 而不是&amp;Rc&lt;T&gt;。自动取消引用也有决胜局,但它们非常清楚,通常是您想要的。

    【讨论】:

    • 您的第一段似乎与我无关。 Rust 很容易让 autoref 无处不在。这是一个有意识的决定,因为它会使代码变得不那么清晰。
    • @ChrisMorgan 我想我主要是想描述一种更好的方式来思考 Rust 的引用,可以这么说来设置舞台。我还了解到,在 C++ 中只有 T &amp;const T &amp;,没有 T &amp; &amp; 或任何东西。
    【解决方案2】:

    在我的理解中,自动借用是一种符合人体工程学的设计

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-08
      • 1970-01-01
      • 2019-02-17
      • 2019-12-12
      • 2016-09-23
      相关资源
      最近更新 更多