我需要存储一个随机大小的字符串的2D网格。我很难操纵Rust向量。这是我所做的:
let mut grid : Vec<&mut Vec<String>> = Vec::new();
let mut v0 : Vec<String> = Vec::new();
let mut v1 : Vec<String> = Vec::new();
v0.push("first string into v0".to_string());
v1.push("first string into v1".to_string());
grid.push(&mut v0); // in position 0
grid.push(&mut v1);
println!("{:?}", &grid);
它返回(按预期)
[[“第一个字符串输入到v0”],[“第一个字符串输入到v1”]]
稍后,我想向v0添加一个字符串
let t1 = grid.get_mut(0);
let t2 = t1.unwrap();
t2.push("A new string into v0".to_string());
println!("{:?}", &grid);
则输出为:
[[“第一个字符串输入v0”,“新字符串输入v0”],[“第一个字符串输入v1”]]
因此,它起作用了,但是当使用向量的向量时它是最佳解决方案吗?
答案 0 :(得分:0)
这取决于您打算如何处理(即“最佳”在这里的意思),但是如果您知道网格的预期大小,则可以展平Vec
。可以使用一个(n x m)个长度的Vec
而不是一个包含m个长度&mut Vec<String>
的n个长度Vec<&mut String>
,然后计算出等效索引的位置,例如而不是grid[2][5]
,而是grid[2*m + 5]
。
您需要一个哨兵来表示未分配:也许是""
,或者您可以Vec<&mut Option<String>>
并使用None
。
答案 1 :(得分:0)
您所做的一切几乎都正确。我想到的第一个问题是,为什么要使用Vec<&mut Vec<String>>
。在那种情况下,vecs v0和v1必须超过网格寿命,这不一定是个好主意。我建议您使用Vec<Vec<String>>
。
乔尔·伯克利(Joel Berkeley)在回答中建议您可以将Vector展平,但他没有解释为什么要在网格中进行此操作。原因是rust 2D向量将始终指向其他向量,从而使CPU采取两种间接方式来获取真实数据,这不利于缓存局部性,具体取决于您在做什么或不在乎。如果您要编写真正的高性能代码,则可能需要这样做,而且还取决于所设计的应用程序类型,因此您不应该在手之前对代码进行预优化:https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil
如果可能的话,我也建议使用vec!
宏来定义向量:https://doc.rust-lang.org/std/macro.vec.html