代码之家  ›  专栏  ›  技术社区  ›  mrspl

为什么取消引用元组上的匹配不起作用,而取消引用非元组却起作用?

  •  1
  • mrspl  · 技术社区  · 7 年前

    我在想办法 Vec 共个枚举。请忽略排序机制本身,这只是一个简单的示例。

    use std::cmp::Ordering;
    
    enum MyEnum {
        Option1,
        Option2,
    }
    
    fn main() {
        let mut my_list: Vec<MyEnum> = vec![MyEnum::Option1, MyEnum::Option2, MyEnum::Option1];
    
        // (1) - doesn't work
        my_list.sort_unstable_by(|a, b| match (*a, *b) {
            (MyEnum::Option1, MyEnum::Option1) => Ordering::Equal,
            (MyEnum::Option1, MyEnum::Option2) => Ordering::Less,
            _  => Ordering::Greater
        });
    }
    

    我得到以下错误:

    error[E0507]: cannot move out of borrowed content
      --> src/main.rs:12:44
       |
    12 |     my_list.sort_unstable_by(|a, b| match (*a, *b) {
       |                                            ^^ cannot move out of borrowed content
    

    以下两种变体适用:

    // (2)
    my_list.sort_unstable_by(|a, _b| match *a {
        MyEnum::Option1 => Ordering::Less,
        MyEnum::Option2 => Ordering::Greater
    });
    
    // (3)
    my_list.sort_unstable_by(|a, b| match (a, b) {
        (&MyEnum::Option1, &MyEnum::Option1) => Ordering::Equal,
        (&MyEnum::Option1, &MyEnum::Option2) => Ordering::Less,
        _  => Ordering::Greater
    });
    

    当我想匹配普通引用时,我可以取消引用它(变体2);为什么在变量1的元组中不起作用?

    我理解为什么3能起作用,但我很难理解1中的具体动作发生在哪里,以及如何以不同的方式进行。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Shepmaster Tim Diekmann    7 年前

    发生移动的确切位置

    编译器指向的位置发生移动 *a . 您正在移动的内容 a 变成一个全新的元组。您不能这样做,因此编译器会给出一个错误。

    编译器提供了在不真正取消引用的情况下“取消引用”匹配变量的能力,这是一些语法上的优点,但它非常有限。它没有“看到”表达式,它只查看一些选定的语法结构,知道如何忽略它们。

    它是 可能的 编译器可以得到增强以查看这些情况,但此时成本/收益权衡可能并不有利。

    另请参见: