gpt4 book ai didi

struct - 如何通过字符串名称设置结构字段值?

转载 作者:行者123 更新时间:2023-11-29 07:58:44 25 4
gpt4 key购买 nike

出于解释型编程语言的习惯,我想根据它们的键重写许多值。我假设我会将所有信息存储在为该项目准备的结构中。所以我开始迭代:

struct Container {
x: String,
y: String,
z: String
}
impl Container {
// (...)
fn load_data(&self, data: &HashMap<String, String>) {
let valid_keys = vec_of_strings![ // It's simple vector with Strings
"x", "y", "z"
] ;
for key_name in &valid_keys {
if data.contains_key(key_name) {
self[key_name] = Some(data.get(key_name);
// It's invalid of course but
// I do not know how to write it correctly.
// For example, in PHP I would write it like this:
// $this[$key_name] = $data[$key_name];
}
}
}
// (...)
}

也许是宏?我尝试使用它们。 key_name 总是按原样解释,我无法获取 key_name 的值。

如何在不为每个值重复代码的情况下执行此操作?

最佳答案

对于宏,我总是主张从直接代码开始,然后看有哪些重复。在这种情况下,我们将从

fn load_data(&mut self, data: &HashMap<String, String>) {
if let Some(v) = data.get("x") {
self.x = v.clone();
}
if let Some(v) = data.get("y") {
self.y = v.clone();
}
if let Some(v) = data.get("z") {
self.z = v.clone();
}
}

注意差异的数量:

  1. 结构必须采用&mut self
  2. 检查一个值是否存在然后单独获取它是低效的。
  3. 我们需要克隆值,因为我们只有一个引用。
  4. 我们不能在 String 中存储 Option

一旦您的代码运行起来,您就可以了解如何抽象事物。 总是首先尝试使用“更轻量级”的抽象(函数、特征等)。只有在用尽之后,我才会开始引入宏。让我们从使用 stringify

开始
if let Some(v) = data.get(stringify!(x)) {
self.x = v.clone();
}

然后你可以提取出一个宏:

macro_rules! thing {
($this: ident, $data: ident, $($name: ident),+) => {
$(
if let Some(v) = $data.get(stringify!($name)) {
$this.$name = v.clone();
}
)+
};
}

impl Container {
fn load_data(&mut self, data: &HashMap<String, String>) {
thing!(self, data, x, y, z);
}
}

fn main() {
let mut c = Container::default();
let d: HashMap<_, _> = vec![("x".into(), "alpha".into())].into_iter().collect();

c.load_data(&d);

println!("{:?}", c);
}

全面披露:我认为这不是一个好主意。

关于struct - 如何通过字符串名称设置结构字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44789286/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com