如何动态访问结构属性?

Hen*_*nry 1 rust

我是 Rust 初学者,想知道如何struct动态访问 a的字段:

use std::collections::HashMap;

struct User {
    email: String,
    name: String,
}

impl User {
    fn new(attributes: &HashMap<String,String>) -> User {
        let mut model = User {
            email: "",
            name: "",
        };

        for (attr_name,attr_value) in attributes {
            // assign value "attr_value" to attribute "attr_name"
            // no glue how to do this
            // in php would be: $model->{$attr_name} = $attr_value;
            model.*attr_name *= attr_value;
        }

        model;
    }
}

fn main() {
    
    let mut map: HashMap::new();
    map.insert("email",String::from("foo@bar.de"));
    map.insert("name",String::from("John doe"));

    user_model = User::new(&map);

    println!("{:?}",user_model);
}
Run Code Online (Sandbox Code Playgroud)

如何struct通过给定初始化 a HashMap

Val*_*tin 5

除非你改变你User的包含一个HashMap然后 Rust不能做那种“魔法” (或者它需要一些 proc 宏的使用,这对初学者不友好)

相反,您可以使用match, 并匹配所有键并更新User字段:

for (attr_name, attr_value) in attributes {
    match attr_name {
        "email" => model.email = attr_value.clone(),
        "name" => model.name = attr_value.clone(),
        _ => {}
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,String我建议不要使用空的s,而是使用Option<String>.

struct User {
    email: Option<String>,
    name: Option<String>,
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将整个new方法简化为:

fn new(attributes: &HashMap<String, String>) -> User {
    User {
        email: attributes.get("email").cloned(),
        name: attributes.get("name").cloned(),
    }
}
Run Code Online (Sandbox Code Playgroud)

由于您有一些混合String&'static str使用,以及Debug未实施。然后这里是完整的例子:

use std::collections::HashMap;

#[derive(Debug)]
struct User {
    email: Option<String>,
    name: Option<String>,
}

impl User {
    fn new(attributes: &HashMap<String, String>) -> User {
        User {
            email: attributes.get("email").cloned(),
            name: attributes.get("name").cloned(),
        }
    }
}

fn main() {
    let mut map = HashMap::new();
    map.insert(String::from("email"), String::from("foo@bar.de"));
    map.insert(String::from("name"), String::from("John doe"));

    let user_model = User::new(&map);

    println!("{:?}", user_model);
}
Run Code Online (Sandbox Code Playgroud)