操纵字符串的双重向量时的最佳实践是什么

时间:2019-05-04 17:07:11

标签: rust

我需要存储一个随机大小的字符串的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”]]

因此,它起作用了,但是当使用向量的向量时它是最佳解决方案吗?

2 个答案:

答案 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