你如何在比赛中借用可变引用?

How do you borrow a mutable reference during a match?

我找到了 this 但我的代码无法运行。我仍然偷偷怀疑我需要 ref 以某种方式。

我正在尝试在 Rust 中做一个合理的 Table class 来学习更多关于该语言的知识,并且 运行 在理解借用检查器和可变性概念以及他们相应的语法。

我希望 table class 灵活并允许不同的列类型,其中列中的数据类型是同类的。因此,一列整数、浮点数、字符串等


我一开始并没有灵活的数据类型,而是想出了 this 哈希映射映射整数(在本例中为列标签)到整数向量(列中的数据)。

use std::collections::HashMap; 

fn main() {
    let mut d: HashMap<isize, Vec<isize>> = HashMap::new();
    d.insert(0, Vec::new());
    d.get_mut(&0).unwrap().push(0); 

    println!("{:?}", d);
    // nice {0: [0]}
}

为了实现灵活的数据类型,enum 似乎是一个不错的开始,所以 that is where I started 但我坚持执行。

use std::collections::HashMap; 

#[derive(Debug)] 
enum VT {
    A(Vec<isize>),
    B(Vec<f64>),
}

fn main() {
    let mut d: HashMap<isize, VT> = HashMap::new();
    d.insert(0, VT::A(Vec::new()));

    match d.get_mut(&0).unwrap() {
        &mut VT::A(v) => v.push(0),
        &mut VT::B(v) => v.push(0.1), // would not be reached as-is 
    } 

    println!("{:?}", d);
}
// cannot borrow immutable local variable `v` as mutable :(

最终,拥有一个类似于 pandas 的图书馆将成为梦想。目前,实施 table 是 Rust 的良好实践。

Rust 1.26开始,任何&/ref&mut/ref mut对都可以省略,编译器推断它们。 (这是一个稍微简单的解释,但它是它的本质。)

match d.get_mut(&0).unwrap() {
    VT::A(v) => v.push(0),
    VT::B(v) => v.push(0.1),
}

在 Rust 1.26 之前(从 2018 年年中开始,所以现在任何读者都可能使用更新的版本),按照以下两个之一编写你的匹配块:

match d.get_mut(&0).unwrap() {
    &mut VT::A(ref mut v) => v.push(0),
    &mut VT::B(ref mut v) => v.push(0.1),
}
match *d.get_mut(&0).unwrap() {
    VT::A(ref mut v) => v.push(0),
    VT::B(ref mut v) => v.push(0.1),
}

在模式中 ref mut 采用可变引用,即使 &mut 取消引用可变引用也是如此。

(通常首选的约定是 match *foo { X => … } 而不是 match foo { &mut X => … },因为更多的匹配分支线上的噪声更少,但在 Rust 1.26 更改后它翻转了另一种方式,因为现在 的相关噪音较小。)