创建包含对另一个集合中项目的引用的集合
Create collection containing references to items in another collection
我有一个按列组织的 table,我想创建一个行向量,这些行是哈希映射,其值是对列中等效值的 mutable 引用,因此然后我可以遍历行,更改将更新原始列中的值的值。我认为这可能是创建一个行的迭代器,而不是一个行的向量,但我更愿意先学习如何做一个向量(如果可能的话),因为这个项目是为了我学习生锈。以下是我到目前为止所拥有的,但我收到了错误
cannot borrow `columns` as mutable more than once at a time
`columns` was mutably borrowed here in the previous iteration of the loop
我找不到解决办法。在下面,我创建 columns
来保存原始数据,rows
应该保存对 columns
中数据的引用,然后我尝试通过获取 [=] 来更新 columns
16=] 来自 rows
并为其分配一个新值。
use std::collections::HashMap;
#[derive(Debug)]
struct Column {
name: String,
data: Vec<i32>,
}
fn main() {
let mut columns = vec![
Column {
name: String::from("col1"),
data: vec![4, 5, 6],
},
Column {
name: String::from("col2"),
data: vec![7, 8, 9],
},
];
println!("{:?}", columns);
let mut rows = Vec::new();
let columns_len = columns[0].data.len();
for i in 0..columns_len {
let mut row = HashMap::new();
for column in columns.iter_mut() {
row.insert(&column.name, column.data.get_mut(i).unwrap());
}
rows.push(row);
}
println!("{:?}", rows);
let cell = rows
.get_mut(1)
.unwrap()
.get_mut(&String::from("col2"))
.unwrap();
println!("{:?}", cell);
**cell = 99;
println!("{:?}", columns);
println!("{:?}", rows);
println!("{:?}", cell);
}
很多时候,将可变引用视为独占 引用很有用。也就是说,与其认为它们允许您修改值,不如将它们视为保证这是唯一可以使用该值的 live 引用,并且可变性只是一个很好的副作用。
考虑到这一点,如果您设法获得 Vec
对 columns
的各个值的可变引用,那么 columns
本身将无法访问(记住,独家访问权)。
并且当您创建 cell
时,它是对 rows
向量的独占引用,那么该向量将在 cell
.
的生命周期内不可访问
就是说,只要小心使用迭代器 API(get_mut()
不会这样做是因为编译器无法确保您不会两次使用相同的索引):
// First create the hash maps
let mut rows = std::iter::repeat_with(|| HashMap::new())
.take(columns[0].data.len())
.collect::<Vec<_>>();
// Then fill in the references.
for c in columns.iter_mut() {
for (id, d) in c.data.iter_mut().enumerate() {
rows[id].insert(c.name.as_str(), d);
}
}
请注意,rows
变量的类型为:Vec<HashMap<&str, &mut i32>>
,我不知道它是否会有用。
在实际的 Rust 中,很多时候将值的索引存储在 Vec
中而不是对内部值的引用更容易。你可能认为它不是那么高效,但是想想如果你压入vector并且它必须重新分配它的内部内存会发生什么!
我有一个按列组织的 table,我想创建一个行向量,这些行是哈希映射,其值是对列中等效值的 mutable 引用,因此然后我可以遍历行,更改将更新原始列中的值的值。我认为这可能是创建一个行的迭代器,而不是一个行的向量,但我更愿意先学习如何做一个向量(如果可能的话),因为这个项目是为了我学习生锈。以下是我到目前为止所拥有的,但我收到了错误
cannot borrow `columns` as mutable more than once at a time
`columns` was mutably borrowed here in the previous iteration of the loop
我找不到解决办法。在下面,我创建 columns
来保存原始数据,rows
应该保存对 columns
中数据的引用,然后我尝试通过获取 [=] 来更新 columns
16=] 来自 rows
并为其分配一个新值。
use std::collections::HashMap;
#[derive(Debug)]
struct Column {
name: String,
data: Vec<i32>,
}
fn main() {
let mut columns = vec![
Column {
name: String::from("col1"),
data: vec![4, 5, 6],
},
Column {
name: String::from("col2"),
data: vec![7, 8, 9],
},
];
println!("{:?}", columns);
let mut rows = Vec::new();
let columns_len = columns[0].data.len();
for i in 0..columns_len {
let mut row = HashMap::new();
for column in columns.iter_mut() {
row.insert(&column.name, column.data.get_mut(i).unwrap());
}
rows.push(row);
}
println!("{:?}", rows);
let cell = rows
.get_mut(1)
.unwrap()
.get_mut(&String::from("col2"))
.unwrap();
println!("{:?}", cell);
**cell = 99;
println!("{:?}", columns);
println!("{:?}", rows);
println!("{:?}", cell);
}
很多时候,将可变引用视为独占 引用很有用。也就是说,与其认为它们允许您修改值,不如将它们视为保证这是唯一可以使用该值的 live 引用,并且可变性只是一个很好的副作用。
考虑到这一点,如果您设法获得 Vec
对 columns
的各个值的可变引用,那么 columns
本身将无法访问(记住,独家访问权)。
并且当您创建 cell
时,它是对 rows
向量的独占引用,那么该向量将在 cell
.
就是说,只要小心使用迭代器 API(get_mut()
不会这样做是因为编译器无法确保您不会两次使用相同的索引):
// First create the hash maps
let mut rows = std::iter::repeat_with(|| HashMap::new())
.take(columns[0].data.len())
.collect::<Vec<_>>();
// Then fill in the references.
for c in columns.iter_mut() {
for (id, d) in c.data.iter_mut().enumerate() {
rows[id].insert(c.name.as_str(), d);
}
}
请注意,rows
变量的类型为:Vec<HashMap<&str, &mut i32>>
,我不知道它是否会有用。
在实际的 Rust 中,很多时候将值的索引存储在 Vec
中而不是对内部值的引用更容易。你可能认为它不是那么高效,但是想想如果你压入vector并且它必须重新分配它的内部内存会发生什么!