Rust中的平面嵌套结果

问题描述 投票:1回答:1

我正在使用提供基于树的数据结构的第三方库(这意味着我必须使用它as is),API函数返回Result<Data, Error>。就我而言,我必须进行一些顺序调用并将错误转换为应用程序的内部。

例如:

use std::error::Error;
use std::fmt;

pub struct Tree {
    branches: Vec<Tree>
}

impl Tree {
    pub fn new(branches: Vec<Tree>) -> Self {
        Tree { branches }
    }

    pub fn get_branch(&self, id: usize) -> Result<&Tree, TreeError> {
        self.branches.get(id).ok_or(TreeError { description: "not found".to_string() })
    }
}

#[derive(Debug)]
pub struct TreeError {
    description: String,
}

impl Error for TreeError {
    fn description(&self) -> &str {
        self.description.as_str()
    }
}

impl fmt::Display for TreeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.description.fmt(f)
    }
}

#[derive(Debug)]
pub struct MyAwesomeError {
    description: String,
}

impl MyAwesomeError {
    pub fn from<T: fmt::Debug>(t: T) -> Self {
        MyAwesomeError {
            description: format!("{:?}", t),
        }
    }
}

impl Error for MyAwesomeError {
    fn description(&self) -> &str {
        &self.description
    }
}

impl fmt::Display for MyAwesomeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.description.fmt(f)
    }
}

如果我编写类似的代码:

pub fn take_first_three_times(tree: &Tree) -> Result<&Tree, MyAwesomeError> {
    let result = tree.get_branch(0)
        .map(|r| r.get_branch(0))
        .map(|r| r.map(|r| r.get_branch(0)));
    ...
}

result的类型将是Result<Result<Result<Tree, TreeError>, TreeError>, TreeError>。当然,我不想通过match的级联来处理错误。

我可以编写一个适应API接口的“内部”函数,并处理基本函数级别的错误:

fn take_first_three_times_internal(tree: &Tree) -> Result<&Tree, TreeError> {
    tree.get_branch(0)?.get_branch(0)?.get_branch(0)
}

pub fn take_first_three_times(tree: &Tree) -> Result<&Tree, MyAwesomeError> {
    take_first_three_times_internal(tree).map_err(MyAwesomeError::from)
}

但是,如果没有附加功能,如何实现它呢?

error-handling rust flatten
1个回答
1
投票

[这是一个示例,当您在函数式编程中使用Option之类的各种包装时。在函数式编程中,有所谓的“纯”函数,它们不更改某些状态(全局变量,输出参数)而仅依赖于输入参数,并且仅将其结果作为返回值返回而没有任何副作用。它使程序更具可预测性和安全性,但带来了一些不便。

© www.soinside.com 2019 - 2024. All rights reserved.