【问题标题】:Rust Double Reference ValueRust 双重参考值
【发布时间】:2021-03-09 12:57:42
【问题描述】:

浏览 Rust 的 blurz 蓝牙库。

声明了一个变量,其值等于临时值的引用(?)。

这个值然后通过引用传递给另一个函数。

如何处理在单个语句中设置为引用值的变量的所有权,然后将该引用用作引用意味着什么?

例子:

let bt_session = &Session::create_session(None)?;
let adapter: Adapter = Adapter::init(bt_session)?;
adapter.set_powered(true)?;

let session = DiscoverySession::create_session(
    &bt_session,
    adapter.get_id()
)?;

查看变量bt_session

Source code example link.

【问题讨论】:

  • 你能澄清你的问题吗? “x 是如何工作的?”有点模棱两可。您能解释一下您发现共享代码示例的错误或混淆之处吗?
  • 试图更新问题,但实际上,我不清楚语法是什么借用含义和参考树。
  • 这能回答你的问题吗? Why is it legal to borrow a temporary?

标签: rust reference borrow-checker ownership borrowing


【解决方案1】:

一个注释的例子来说明一些概念:

use rand;

#[derive(Debug)]
struct Struct {
    id: i32
}

impl Drop for Struct {
    fn drop(&mut self) {
        // print when struct is dropped
        println!("dropped {:?}", self);
    }
}

fn rand_struct() -> Struct {
    Struct { id: rand::random() }
}

/*
this does not compile:

fn rand_struct_ref<'a>() -> &'a Struct {
    &rand_struct()
    // struct dropped here so we can't return it to caller's scope
}
*/

fn takes_struct_ref(s: &Struct) {}

fn main() {
    // brings struct into scope and immediately creates ref to it
    // this is okay because the struct is not dropped until end of this scope
    let s = &rand_struct();
    
    println!("holding ref to {:?}", s);
    
    // all these work because of deref coercion
    takes_struct_ref(s);
    takes_struct_ref(&s);
    takes_struct_ref(&&s);
    
    // struct dropped here
}

playground

回答您的第一个问题:如果在函数末尾删除了基础值,则无法从函数返回引用,但可以立即引用返回的值,因为该值在其余部分都存在调用者的范围。如果您运行上面的示例,您可以看到这一点,因为holding ref to Struct { id: &lt;id&gt; } 将在dropped Struct { id: &lt;id&gt; } 之前打印。

回答您的第二个问题:您可以将&amp;Struct&amp;&amp;Struct&amp;&amp;&amp;Struct 等传递给只需要&amp;Struct 的函数的原因是因为名为deref coercion 当变量用作函数参数或作为方法调用的一部分时,它会自动解除对变量的引用。在您的共享代码示例中看起来一个引用的引用被传递给函数但实际上它只是在自动解除引用强制发生后传递一个引用。 p>

另见

【讨论】:

  • 为了清楚起见,&s 参数的全部目的是什么?有没有使用 && 或 &&& 的理由?
  • 如果函数(无论出于何种原因)特别需要 && 或 &&&,则必须使用 && 或 &&&。另外,如果 s 已经是一个引用,我不会说当函数需要一个引用时你应该写 &s 。我不知道为什么 test6 会这样做,但我最好的猜测是作者正在重构一些代码并且忘记在变量前面删除不必要的 &。
  • 感谢您深思熟虑的回复以及示例并分享一些直觉,现在这更有意义了。
猜你喜欢
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
相关资源
最近更新 更多