gpt4 book ai didi

rust - 使用 `and_then`如何返回Result <(),String>

转载 作者:行者123 更新时间:2023-12-03 11:43:10 24 4
gpt4 key购买 nike

我正在使用带有自定义验证器的clap,如下所示:

.arg(
Arg::with_name("config")
.help("config.yml")
.long("config")
.default_value("config.yml")
.short("c")
.required(true)
.value_name("FILE")
.validator(is_file),
)

这是我正在使用的工作验证程序 is_file:

fn is_file(s: String) -> Result<(), String> {
let metadata = match metadata(&s) {
Err(err) => return Err(err.to_string()),
Ok(metadata) => metadata,
};
if !metadata.is_file() {
return Err(format!("cannot read file: {}", s));
}
Ok(())
}

阅读有关 std::result::Result 的更多信息后,我发现它具有多种方法,可用于简化或显着减少代码。

为了简化 is_file我正在尝试:

fn is_file(s: String) -> Result<(), String> {
metadata(&s).and_then(|m| (!m.is_file()))
}

我的问题是 !m.is_file()返回 bool:

 metadata(&s).and_then(|m| !m.is_file())
| ^^^^^^^^^^^^
| |
| expected enum `std::result::Result`, found `bool`
| help: try using a variant of the expected enum: `Ok(!m.i


使用 and_thenResult中的其他方法,如何简化 is_file函数?

最佳答案

您需要自己创建Result,但是您可以使用问号运算符和map_err()删除match语句:

fn is_file(s: String) -> Result<(), String> {
if metadata(&s).map_err(|e| e.to_string())?.is_file() {
Ok(())
} else {
Err(format!("cannot read file: {}", s))
}
}

或按照您的建议使用 and_then():
fn is_file(s: String) -> Result<(), String> {
metadata(&s).map_err(|e| e.to_string()).and_then(|m| {
if m.is_file() {
Ok(())
} else {
Err(format!("cannot read file: {}", s))
}
})
}

我想说这是否比您的原始代码更好。

将来,如果有类似 then_some() Result ,您可能可以不用if-else编写它。

关于rust - 使用 `and_then`如何返回Result <(),String>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61933282/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com