什么时候应该“&”在任务的两边使用?

时间:2016-06-15 13:00:31

标签: pointers rust dereference borrow-checker borrowing

Condvar文档显示了一个示例,其中包含以下内容:

let pair = Arc::new((Mutex::new(false), Condvar::new()));
// <snipped for brevity>
let &(ref lock, ref cvar) = &*pair;

我想知道在这项任务的双方都包括&可能有什么好处。换句话说,为什么不写:

let (ref lock, ref cvar) = *pair;

两个版本都编译;是否存在语义差异?如果没有,是否有理由更喜欢示例中出现的语法?

一般来说,我仍然在努力了解何时/ &*应该在Rust代码中出现。我的直觉是“看到”(读取)这个字符组合为无操作,但我理解由于Rust的Deref语义,情况并非如此。

1 个答案:

答案 0 :(得分:3)

在这种情况下使用&没有区别,因为LHS是destructuring pattern。在我看来,这个例子不应该使用&。但是,在其他情况下存在重要差异:*移动延迟值:

let p = *pair; // *Deref::deref(pair)
// pair cannot be used anymore because the deferred value was moved

let p = &*pair; // &*Deref::deref(pair)
// p: &(Mutex::new(false), Condvar::new())
// p and pair can be used
  

我仍然在努力了解什么时候/哪里&amp; *应该在Rust代码中出现。

通常,在需要引用延迟值时使用&*,就像在函数调用中一样:

fn sum(a: &u32, b: &u32) -> u32 {
   a + b
}

fn main() {
    let x = Box::new(10);
    // println!("{:?}", sum(&1, x)); // do not work x is Box<u32>
    // println!("{:?}", sum(&1, *x)); // do not work *x is u32
    println!("{:?}", sum(&1, &*x)); // ok &*x is &u32
}
  

我的直觉是“看”(读)这个字符组合为无操作,但我明白因为Rust的Deref语义而不是这种情况。

考虑到The Book说“Deref对于编写自定义指针类型很有用”,我喜欢将&*读作“对此(智能)指针指向的值的引用” ”