首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不同Err类型的嵌套结果的平坦化

不同Err类型的嵌套结果的平坦化
EN

Stack Overflow用户
提问于 2022-07-11 16:44:13
回答 2查看 89关注 0票数 0

this answer之后,当它们有不同的错误类型时,如何使其扁平化。

以下是我想要达到的目标:

代码语言:javascript
运行
复制
let length: usize = std::env::var("LENGTH").and_then(|id| id.parse::<usize>()).unwrap_or(8);

但是,编译器引发以下错误:

errorE0308:不匹配类型

预期枚举VarError,发现了struct ParseIntError

id.parse::<usize>()

是否有办法做到这一点,或者我是否被更丑陋的选择所困扰:

代码语言:javascript
运行
复制
let length: usize = std::env::var("LENGTH").unwrap_or_else(|_| 8.to_string()).parse().unwrap_or(8);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-11 18:32:03

可以使用Result::ok()Result转换为Option,放弃Err并将其替换为None

代码语言:javascript
运行
复制
fn main() {
    let length: usize = std::env::var("LENGTH")
        .ok()
        .and_then(|id| id.parse::<usize>().ok())
        .unwrap_or(8);
    println!("{length}");
}
票数 1
EN

Stack Overflow用户

发布于 2022-07-11 18:49:16

对于你的情况,@JeremyMeadows的答案可能是最好的。

但是通常,如果您想保持错误,您可以执行如下操作:

代码语言:javascript
运行
复制
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);

或者更通用的,这可能是我在自己的项目中所做的:

代码语言:javascript
运行
复制
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);
}

或者,如果我的项目更专业:

代码语言:javascript
运行
复制
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);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72941926

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档