Struct 如何按字符串名称设置结构字段值?
出于解释型编程语言的习惯,我想根据它们的键重写许多值。我假设我会将所有信息存储在为该项目准备的结构中。所以我开始迭代:Struct 如何按字符串名称设置结构字段值?,struct,rust,Struct,Rust,出于解释型编程语言的习惯,我想根据它们的键重写许多值。我假设我会将所有信息存储在为该项目准备的结构中。所以我开始迭代: struct Container { x: String, y: String, z: String } impl Container { // (...) fn load_data(&self, data: &HashMap<String, String>) { let valid_k
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];
}
}
}
// (...)
}
struct容器{
x:字符串,
y:弦,
z:字符串
}
impl容器{
// (...)
fn加载\u数据(&self,数据:&HashMap){
让valid_keys=vec_of_strings![//这是带字符串的简单向量
“x”、“y”、“z”
] ;
对于有效密钥中的密钥名称(&U){
如果数据包含密钥(密钥名称){
self[key\u name]=Some(data.get)(key\u name);
//当然无效,但是
//我不知道如何正确地写。
//例如,在PHP中,我会这样写:
//$this[$key\u name]=$data[$key\u name];
}
}
}
// (...)
}
可能是宏?我试过使用它们。key\u name
总是按原样解释,我无法取而代之的是key\u 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();
}
}
然后,您可以提取一个宏:
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);
}
宏规则!东西{
($this:ident,$data:ident,$($name:ident),+)=>{
$(
如果让Some(v)=$data.get(stringify!($name)){
$this.$name=v.clone();
}
)+
};
}
impl容器{
fn加载\u数据(&mut self,数据:&HashMap){
东西!(自我,数据,x,y,z);
}
}
fn main(){
让mut c=Container::default();
设d:HashMap=vec![(“x.into(),“alpha.into())]into_iter().collect();
c、 加载数据(&d);
println!(“{:?}”,c);
}
充分披露:我认为这不是一个好主意。您应该首先检查您的用例是否仅包含在本文档中。
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);
}