元组如何被分解为参考? [英] How are Tuples destructured into references?

查看:68
本文介绍了元组如何被分解为参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看 Condvar 示例,并很好奇元组 pair pair2 的结构如何:

I'm looking at the Condvar example and am curious how the tuples pair and pair2 are destructured:

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = pair.clone();
// ...

thread::spawn(move|| {
    let &(ref lock, ref cvar) = &*pair2;
    // ...
}

pair2 中删除& :

let &(ref lock, ref cvar) = *pair2;

产生了我期望的编译器错误:

gives a compiler error as I expected:

11 |     let &(ref lock, ref cvar) = *pair2;
   |         ^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
   |
   = note: expected type `(std::sync::Mutex<bool>, std::sync::Condvar)`
              found type `&_`

但是,如果删除元组周围的& ,它似乎可以编译并运行良好:

However, it seems to compile and run fine if the & around the tuple is removed:

let (ref lock, ref cvar) = &*pair2;

,或者两个& 都被删除了:

or if both of the &'s are removed:

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

或什至

let (lock, cvar) = &*pair2;

在后一种情况下,编译器是否在帮助我们?

Is the compiler is helping us in the latter cases?

推荐答案

编译器正在帮助我们使用匹配人体工程学.匹配人体工程学适用于元组分解和 match 表达式;我们将首先查看 match 表达式的情况.

The compiler is helping us using match ergonomics. Match ergonomics applies to tuple destructuring and the match expression; we'll look at the case of the match expression first.

匹配人体工程学简化了引用非引用模式匹配时Rust绑定变量的方式:

Match ergonomics simplifies how Rust binds variables when a reference is matched to a non-reference pattern:

let x = Some(42);
let x_ref = &x;

match x_ref { // <-- reference match expression: `x_ref`
    Some(a) => {}, // <-- non-reference pattern: `Some(a)`
    None => {},
}

较旧版本的Rust编译器不允许这样做.相反,必须在模式中指定引用(& ):

Older version of the Rust compiler didn't allow this. Instead, one had to either specify references (&) in the pattern:

// Old Rust
match x_ref {
    &Some(a) => {},
    &None => {},
}

或在匹配前取消引用:

// Old Rust
match *x_ref {
    Some(a) => {},
    None => {},
}

请注意, a 拥有 Option 的内部值,这对于非 Copy 类型来说是有问题的.为了避免这种情况,还必须借用内在价值.这是通过使用 ref 关键字将 a 绑定为参考来完成的:

Notice that a owns the Option's inner value, which is problematic for non-Copy types. To avoid this, one also had to borrow the inner value. This is done by binding a as a reference using the ref keyword:

// Old Rust
let x = Some(Box::new(42));
let x_ref = &x;

match x_ref {
    &Some(ref a) => {},
    &None => {},
}

// Old Rust
match *x_ref {
    Some(ref a) => {},
    None => {},
}

Rust的新匹配人体工程学允许使用简化版本:

Rust's new match ergonomics allow a simplified version:

// New Rust
match x_ref {
    Some(a) => {
        // x_ref is automatically dereferenced
        // a is automatically bound as a reference
    },
    None => {},
}

用于 Copy 和非 Copy 类型.

将其应用于元组销毁,

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let (lock, cvar) = &*pair;
//                 ^^^^^^ reference match expression
//  ^^^^^^^^^^^^ non-reference pattern

  • * pair 是一个元组
  • & * pair 是对元组的引用
  • lock cvar 均被绑定为引用
查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆