在this answer之后,当它们有不同的错误类型时,如何使其扁平化。
以下是我想要达到的目标:
let length: usize = std::env::var("LENGTH").and_then(|id| id.parse::<usize>()).unwrap_or(8);
但是,编译器引发以下错误:
errorE0308:不匹配类型
预期枚举VarError
,发现了struct ParseIntError
在id.parse::<usize>()
。
是否有办法做到这一点,或者我是否被更丑陋的选择所困扰:
let length: usize = std::env::var("LENGTH").unwrap_or_else(|_| 8.to_string()).parse().unwrap_or(8);
发布于 2022-07-11 18:32:03
可以使用Result::ok()
将Result
转换为Option
,放弃Err
并将其替换为None
。
fn main() {
let length: usize = std::env::var("LENGTH")
.ok()
.and_then(|id| id.parse::<usize>().ok())
.unwrap_or(8);
println!("{length}");
}
发布于 2022-07-11 18:49:16
对于你的情况,@JeremyMeadows的答案可能是最好的。
但是通常,如果您想保持错误,您可以执行如下操作:
let length: usize = std::env::var("LENGTH")
.map_err(Box::<dyn std::error::Error>::from)
.and_then(|id| id.parse::<usize>().map_err(Into::into))
.unwrap_or(8);
或者更通用的,这可能是我在自己的项目中所做的:
use std::{error::Error, str::FromStr};
fn main() {
fn parse_from_env<T>(key: &str) -> Result<T, Box<dyn Error>>
where
T: FromStr,
<T as FromStr>::Err: Into<Box<dyn std::error::Error>>,
{
std::env::var(key)?.parse().map_err(Into::into)
}
let length: usize = parse_from_env("LENGTH").unwrap_or(8);
}
或者,如果我的项目更专业:
use std::{error::Error, str::FromStr};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum MyErrors {
#[error("unable to read environment variable")]
EnvNotValid(#[source] Box<dyn Error>),
}
fn main() {
fn parse_from_env<T>(key: &str) -> Result<T, MyErrors>
where
T: FromStr,
<T as FromStr>::Err: Into<Box<dyn std::error::Error>>,
{
std::env::var(key)
.map_err(|e| MyErrors::EnvNotValid(e.into()))?
.parse()
.map_err(|e: <T as FromStr>::Err| MyErrors::EnvNotValid(e.into()))
}
let length: usize = parse_from_env("LENGTH").unwrap_or(8);
}
https://stackoverflow.com/questions/72941926
复制相似问题