我正在尝试做类似的事情:
const CONF_PATHS: [&'static str; 2] = ["/etc/foo.conf", "./foo.conf"];
...
let conf = for path in CONF_PATHS {
let load_result = fs::read_to_string(path);
match load_result {
Ok(json) => {
let parse_result: Result<Conf, serde_json::Error> = serde_json::from_str(&json);
match parse_result {
Ok(conf) => conf,
Err(err) => {
warn!("conf parse failure: {}", err);
continue
}
}
},
Err(err) => {
warn!("conf load failure: {}", err);
continue
}
}
};
但是编译器(可以理解)抱怨:
error[E0308]: `match` arms have incompatible types
--> foo/src/main.rs:34:25
|
30 | / match parse_result {
31 | | Ok(conf) => conf,
| | ---- this is found to be of type `Conf`
32 | | Err(err) => {
33 | | warn!("conf parse failure: {}", err);
34 | | continue
| | ^^^^^^^^ expected `Conf`, found `()`
35 | | }
36 | | }
| |_________________- `match` arms have incompatible types
(我希望
continue
会被像 todo!()
一样对待,并且不需要匹配。)
是否可以以任何方式组成循环和匹配?
是否有一种方法可以将值“返回”到封闭范围,而不用将整个范围包装在函数中?
问题不是
continue
。确实是像todo!()
一样对待。问题出在外层match
。由于它不是表达式而是语句,因此它必须返回()
。您可以例如将其分配给变量:
let v = match load_result {
Ok(json) => {
let parse_result: Result<Conf, serde_json::Error> = serde_json::from_str(&json);
match parse_result {
Ok(conf) => conf,
Err(err) => {
warn!("conf parse failure: {}", err);
continue
}
}
},
Err(err) => {
warn!("conf load failure: {}", err);
continue
}
};