以下是一些反馈:
- 如果您已经处理了所有选项,则不要包括
_
个默认匹配大小写.它将隐藏future 的错误.
- 如果每个成员都只是一种数据类型,则不要将变量命名为
DataTypes
.把它命名为DataType
.
result
必须是一个特定的类型.枚举的全部意义在于您可以分别处理不同的值,因此将它们组合在result
类型中是没有意义的.当然,can保留result
个DataType
对象,并为其实现Debug
/Display
,这就是我将在重新编写的代码中如何做到这一点.
- 虽然您先can查询键,然后在循环中再次查询值,但这相当慢.您可以立即迭代键-值对.这样,您就避免了许多
unwrap()
,这使得您的代码更不容易出错.
use std::collections::HashMap;
#[derive(Debug)]
enum DataType {
String(String),
Bool(bool),
}
fn get_hashmap() -> Result<HashMap<String, DataType>, ()> {
let data = HashMap::from([
(
"password".to_string(),
DataType::String("password".to_string()),
),
(
"username".to_string(),
DataType::String("Fun username".to_string()),
),
("is_blocked".to_string(), DataType::Bool(true)),
("is_confirmed".to_string(), DataType::Bool(false)),
]);
Ok(data)
}
fn main() {
let data = get_hashmap().unwrap();
for (key, value) in data {
println!("{}: {:?}", key, value);
match value {
DataType::Bool(value) => {
println!("\tValue was a bool: {}", value);
// do something if the value is a bool
}
DataType::String(value) => {
println!("\tValue was a string: {}", value);
// do something if the value is a string,
} /*
* Don't include a default case. That way the compiler
* will remind you to handle additional enum entries if
* you add them in the future.
* Adding a default case is only a good practice in languages
* where matching is not exhaustive.
*/
};
}
}
username: String("Fun username")
Value was a string: Fun username
is_confirmed: Bool(false)
Value was a bool: false
is_blocked: Bool(true)
Value was a bool: true
password: String("password")
Value was a string: password
不过,不要担心,您不需要在使用此枚举的任何地方都使用match
,否则与两个单独的哈希图相比,您不会获得太多好处.相反,您可以为所有枚举条目定义共享功能,并隐藏其中的match
.就像这样:
use std::collections::HashMap;
#[derive(Debug)]
enum DataType {
String(String),
Bool(bool),
}
impl DataType {
fn do_something(&self) {
match self {
DataType::Bool(value) => {
println!("\tDo something with boolean '{}'!", value);
}
DataType::String(value) => {
println!("\tDo something with string {:?}!", value);
}
};
}
}
fn get_hashmap() -> Result<HashMap<String, DataType>, ()> {
let data = HashMap::from([
(
"password".to_string(),
DataType::String("password".to_string()),
),
(
"username".to_string(),
DataType::String("Fun username".to_string()),
),
("is_blocked".to_string(), DataType::Bool(true)),
("is_confirmed".to_string(), DataType::Bool(false)),
]);
Ok(data)
}
fn main() {
let data = get_hashmap().unwrap();
for (key, value) in data {
println!("{}: {:?}", key, value);
value.do_something();
}
}
is_confirmed: Bool(false)
Do something with boolean 'false'!
password: String("password")
Do something with string "password"!
is_blocked: Bool(true)
Do something with boolean 'true'!
username: String("Fun username")
Do something with string "Fun username"!
如果您的目标是将序列化/反序列化添加到您的 struct 中(就像您在这里手动实现的那样),让我提示您接近serde
,它已经免费处理了大部分序列化.
如本例所示(它可能是也可能不是您的 struct 的样子),它将您的 struct 序列化到JSON和从JSON序列化:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct User {
username: String,
password: String,
is_blocked: bool,
is_confirmed: bool,
}
fn main() {
let user = User {
username: "Fun username".to_string(),
password: "password".to_string(),
is_blocked: true,
is_confirmed: false,
};
let user_serialized = serde_json::to_string(&user).unwrap();
println!("Serialized: {}", user_serialized);
let user_deserialized: User = serde_json::from_str(&user_serialized).unwrap();
println!("Name: {}", user_deserialized.username);
}
Serialized: {"username":"Fun username","password":"password","is_blocked":true,"is_confirmed":false}
Name: Fun username