4

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语义,情况并非如此。

4

1 回答 1

3

在这种情况下使用&没有任何区别,因为 LHS 是一种解构模式。在我看来,这个例子不应该使用&. 但是,在其他情况下有一个重要的区别:*移动延迟值:

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

我仍在努力理解 &* 应该在何时/何地以惯用方式出现在 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 语义,情况并非如此。

考虑到书中说“Deref对于编写自定义指针类型很有用”,我喜欢将其理解&*为“对这个(智能)指针指向的值的引用”。

于 2016-06-15T14:34:41.237 回答