error-handling - 在 Rust : concating results on Ok 中编写错误

标签 error-handling rust

我有以下代码。它有效。

但我更感兴趣的是写make_tea我在哪里调用两个函数:get_milk_from_cowpour_milk .他们都返回 Result<String, TeaError> .

我如何组合它们才能继续连接 String s 如果他们成功,否则返回错误。

enum TeaError {
    NoMilk,
    NoCup,
    NoCow,
    NoGas,
    NoSomething,
}

fn get_milk_from_cow(cow: bool) -> Result<String, TeaError> {
    if cow {
        Ok(String::from("get milk from cow"))
    } else {
        Err(TeaError::NoCow)
    }
}

fn pour_milk(milk: bool) -> Result<String, TeaError> {
    if milk {
        Ok(String::from("poured milk"))
    } else {
        Err(TeaError::NoMilk)
    }
}

fn make_tea() -> Result<String, TeaError> {
    let mut process = String::new();
    let step_cow = get_milk_from_cow(true)?;
    let step_milk = pour_milk(true)?;
    process.push_str(step_cow.as_str());
    process.push_str(step_milk.as_str());
    Ok(process)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn attemp_tea_one() {
        match pour_milk(false) {
            Err(v) => match v {
                TeaError::NoMilk => assert!(true),
                _ => assert!(false)
            },
            Ok(_) => assert!(false)
        };
    }

    #[test]
    fn attemp_tea_two() {
        match make_tea() {
            Err(_) => assert!(false),
            Ok(_) => assert!(true)
        };
    }
}

我试过了:

process.push_str(get_milk_from_cow(true)?
       .push_str(pour_milk(true)?.as_str()))

但它给出了:

error[E0308]: mismatched types
  --> src/errors.rs:27:22
   |
27 |     process.push_str(get_milk_from_cow(true)?.push_str(pour_milk(true)?.as_str()));
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &str, found ()
   |
   = note: expected type `&str`
              found type `()`

作为push_str不返回字符串。

编辑:

fn append(s1: String, s2: String) -> String {
    s1 + s2.as_str()
}
fn make_tea() -> Result<String, TeaError> {
    let process = append(get_milk_from_cow(true)?,
                         pour_milk(true)?);
    Ok(process)
}

所以,我可以做到append(append(funcA(), funcB()), funcC())等等.. 我还在学习关于生命周期的知识,并思考是否append在内存分配方面仍有待改进。

最佳答案

此代码在带星号的行上做了多余的工作:

fn make_tea() -> Result<String, TeaError> {
*   let mut process = String::new();
    let step_cow = get_milk_from_cow(true)?;
    let step_milk = pour_milk(true)?;
*   process.push_str(step_cow.as_str());
    process.push_str(step_milk.as_str());
    Ok(process)
}

process.push_str(step_cow.as_str()) 只是生成一个不需要的 step_cow 副本。相反,尝试

fn make_tea() -> Result<String, TeaError> {
    let mut process = get_milk_from_cow(true)?;
    process.push_str(&pour_milk(true)?);
    Ok(process)
}

或者,更方便的是,

fn make_tea() -> Result<String, TeaError> {
    Ok(get_milk_from_cow(true)? + &pour_milk(true)?)
}

关于error-handling - 在 Rust : concating results on Ok 中编写错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43776706/

相关文章:

c++ - 在C++中,如何获取当前线程的调用堆栈?

rust - 为什么 Rust 需要知道模块中的代码属于谁?

rust - 为什么我需要声明 "extern crate core"才能使用 libcore?

rust - 同一类型的 Add trait 的几种实现

ruby-on-rails - ajax请求上的Ruby on Rails错误500

ruby-on-rails - CSV 解析返回 "Unquoted fields do not allow\r or\n"但在源文件中找不到错误?

iterator - Rust 检查迭代器 : cannot borrow `*` as immutable because it is also borrowed as mutable

rust - 如何在 nom 中构建负向先行解析器?

php - 检测内容是否在 codeigniter 中的 php 文件中的一行之前发送

php - 是否有可能捕获文件中发生的所有 PHP 错误