我有一个结构向量。我想为每个元素添加一个额外的字段。最好的方法是什么?
这样的事情:
// Pseudo code
let items = vec![elem1, elem2, elem3, elem4];
for x in items {
// Something like this
x["some_additional_key"] = get_data(x);
}
//
// Now I have items[i].some_additional_key in each element
答案 0 :(得分:4)
Rust是statically-typed language;您可能熟悉其他类似的语言,如C ++,Java或Swift。在这些语言中,编译程序时,结构的成员,类型和布局是固定的。
正因为如此,没办法在运行时添加新的结构字段 - 没有" ifs"," ands",或者"的击打" - 你不能这样做。
相反,你必须以其他方式对动态性质进行建模:
使用允许任意扩展的类型。 HashMap
和BTreeMap
(以及许多其他类似类型)允许您拥有任意数量的键值对。在幕后,这基本上是有多少动态语言工作 - 将字符串映射到任意值:
use std::collections::HashMap;
#[derive(Debug, Default)]
struct Element(HashMap<String, u8>);
fn get_data(_: &Element) -> u8 {
42
}
fn main() {
let mut items = vec![
Element::default(),
Element::default(),
Element::default(),
Element::default(),
];
for x in &mut items {
let value = get_data(x);
x.0
.entry("some_additional_key".to_string())
.or_insert(value);
}
}
使用允许特定扩展的类型。 Option
允许存在或不存在值:
#[derive(Debug, Default)]
struct Element {
some_additional_key: Option<u8>,
}
fn get_data(_: &Element) -> u8 {
42
}
fn main() {
let mut items = vec![
Element::default(),
Element::default(),
Element::default(),
Element::default(),
];
for x in &mut items {
let value = get_data(x);
x.some_additional_key = Some(value);
}
}
使用构图。创建一个包装现有类型的新类型:
#[derive(Debug, Default)]
struct Element;
#[derive(Debug)]
struct EnhancedElement {
element: Element,
some_additional_key: u8,
}
fn get_data(_: &Element) -> u8 {
42
}
fn main() {
let items = vec![
Element::default(),
Element::default(),
Element::default(),
Element::default(),
];
let enhanced: Vec<_> = items
.into_iter()
.map(|element| {
let some_additional_key = get_data(&element);
EnhancedElement {
element,
some_additional_key,
}
})
.collect();
}
另见: