我试着做一些类似的事情:
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!()
一样被处理,不需要匹配。
- 有没有可能以任何方式组合循环和匹配?
- 有没有一种方法可以“返回”一个值到一个封闭的作用域,而不用将整个作用域 Package 在一个函数中?
作为一个单独的函数的解决方法说明了意图,它是:
const CONF_PATHS: [&'static str; 2] = ["/etc/foo.conf", "./foo.conf"];
const DEFAULT_CONF: Conf = Conf { report_interval: 5 };
/* Load configuration, or use default configuration. */
fn load_conf_or_default() -> 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) => return conf,
Err(err) => {
warn!("conf parse failure: {}", err);
continue
}
}
},
Err(err) => {
warn!("conf load failure: {}", err);
continue
}
}
}
DEFAULT_CONF
}
2条答案
按热度按时间kuarbcqp1#
这里的问题是,
for
并不意味着要在此上下文中使用。for
总是返回()
,你需要它返回一个值。你要在一个函数被应用后,在列表中寻找第一个没有错误的值,所以你可以使用
find_map
来代替for
,就像这样:093gszye2#
问题不在于
continue
。它实际上被视为todo!()
。问题是外部match
。因为它不是一个表达式,而是一个语句,所以它必须返回()
。你可以例如。将其赋值给一个变量: