【发布时间】:2019-08-28 05:26:47
【问题描述】:
我正在接收字符串向量形式的数据,并且需要使用值的子集填充结构,例如this:
const json: &str = r#"["a", "b", "c", "d", "e", "f", "g"]"#;
struct A {
third: String,
first: String,
fifth: String,
}
fn main() {
let data: Vec<String> = serde_json::from_str(json).unwrap();
let a = A {
third: data[2],
first: data[0],
fifth: data[4],
};
}
这不起作用,因为我将值移出向量。编译器认为这会使data 处于可能导致问题的未初始化状态,但因为我再也不会使用data,所以这无关紧要。
传统的解决方案是swap_remove,但它是有问题的,因为元素不是以相反的顺序访问的(假设结构是从上到下填充的)。
我现在通过执行mem::replace 并将data 设置为mut 来解决这个问题,这会使原本干净的代码变得混乱:
fn main() {
let mut data: Vec<String> = serde_json::from_str(json).unwrap();
let a = A {
third: std::mem::replace(&mut data[2], "".to_string()),
first: std::mem::replace(&mut data[0], "".to_string()),
fifth: std::mem::replace(&mut data[4], "".to_string())
};
}
此解决方案是否有替代方案不需要我进行所有这些replace 调用和data 不必要的mut?
【问题讨论】:
-
@SvenMarnach 空字符串不分配,但是
"".to_string()可能不是创建一个的最佳方法。我会选择std::mem::replace(&mut data[2], String::new()),这可能是最好的。如果向量允许移出其元素,则它必须跟踪哪些仍然存在以释放它们,而这最终可能会降低性能。 -
@mcarton 你是对的,我的错。
-
作为一个正在学习 Rust 的人,为什么这比
data.remove(index)更可取,因为我们删除数据时索引会发生变化? -
@evading 不仅只是索引会移动(这很烦人),而且每个
remove调用都必须移动向量中的所有后续数据。这是一个性能问题(尽管很可能是一个很小的问题)。
标签: rust borrow-checker