你如何在比赛中借用可变引用?
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 更改后它翻转了另一种方式,因为现在 的相关噪音较小。)
我找到了 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 更改后它翻转了另一种方式,因为现在 的相关噪音较小。)