rust - 为什么在 Rust 中处理自定义错误类型时会出现运行错误?

标签 rust

这个问题在这里已经有了答案:





Why does my string not match when reading user input from stdin?

(3 个回答)


1年前关闭。




我在使用 .expect() 处理错误时遇到问题.
这是我的代码:
src/main.rs

mod myerrors;

fn main() {
    mytest().expect("incorrrect number");
    //let shows: Vec<Show> = download().expect("read error");
    //print(shows);
}

fn mytest() -> std::result::Result<i8, myerrors::MyError>
{
    let stdin = std::io::stdin();
    let mut line: String = String::new();
    match stdin.read_line(&mut line)
    {
        Ok(_) => {},
        Err(_) => return Err(myerrors::DownloadError),
    };
    let num: i8 = match line.parse::<i8>()
    {
        Ok(num) => num,
        Err(_) => return Err(myerrors::MyError),
    };
    return Ok(num);
}
src/myerrors.rs
pub struct MyError;

impl std::fmt::Debug for MyError
{
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
    {
        f.debug_struct("DownloadError").finish()
    }
}
它可以构建,但在输入 后会崩溃线程 'main' 在 'incorrrect number: DownloadError' 时 panic ,src/main.rs:4:14 .

最佳答案

为什么 .expect() 会导致程序 panic ?
简短的回答是,如果 ResultOk ,然后 .expect()将展开并返回 Ok 中包含的值元组结构。如果 ResultErr ,然后 .expect()会因您指定的消息而 panic 。
在您的情况下,您的 Err(_) 之一似乎mytest() 正在返回值,所以 .expect()main引起 panic 。堆栈跟踪应该给你一个关于哪里出了问题的提示。
一些调试技巧
处理错误而不是 panic
首先,我认为您应该处理 mytest() 的返回值与执行返回 Result 的其他函数的方式相同.这可能如下所示。

fn main() {
    match mytest() {
      Ok(_) => println!("ok!");
      Err(e) => println!("Error: {:?}", e);
    }
}
您当然可以在每个匹配组中做一些不同的事情,但如果可能的话,通常最好不要让您的程序 panic 。
如果可以的话,试试无论如何 crate
因为您忽略了 .read_line() 返回的错误和 .parse() ,您正在失去关于错误所在的上下文。 .with_context()功能可以帮助解决这个问题。
考虑改为像下面这样构建您的代码。
use anyhow::{Context, Result};

fn main() {
    match mytest() {
        Ok(num) => println!("Parsed: {}", num),
        Err(e) => println!("{:?}", e),
    }
}

fn mytest() -> Result<i8> {
    let stdin = std::io::stdin();
    let mut line: String = String::new();
    match stdin.read_line(&mut line) {
        Ok(_) => {}
        Err(e) => return Err(e).with_context(|| format!("Unexpected failure reading stdin")),
    };
    let num: i8 = match line.parse::<i8>() {
        Ok(num) => num,
        Err(e) => {
            return Err(e).with_context(|| format!("Unexpected failure parsing line: {:?}", line))
        }
    };
    return Ok(num);
}
然后你会得到一个类似下面的错误
$ cargo run                                                                                          
   Compiling stdin-debug v0.1.0 (/Users/chcl/Development/learning-rust/projects/stdin-debug)         
    Finished dev [unoptimized + debuginfo] target(s) in 0.39s                                        
     Running `target/debug/stdin-debug`                                                              
123                                                                                                  
Unexpected failure parsing line: "123\n"                                                             
                                                                                                     
Caused by:                                                                                           
    invalid digit found in string                                                                    
现在更明显的是错误在哪里。 line变量包含换行符!正如 Ibraheem Ahmed 指出的那样,您需要 .trim()解析之前的行以确保它不包含空格。
diff --git a/src/main.rs b/src/main.rs
index d07677a..4172e4e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,7 +14,7 @@ fn mytest() -> Result<i8> {
         Ok(_) => {}
         Err(e) => return Err(e).with_context(|| format!("Unexpected failure reading stdin")),
     };
-    let num: i8 = match line.parse::<i8>() {
+    let num: i8 = match line.trim().parse::<i8>() {
         Ok(num) => num,
         Err(e) => {
             return Err(e).with_context(|| format!("Unexpected failure parsing line: {:?}", line))
现在我得到以下信息。 =D
$ cargo run
   Compiling stdin-debug v0.1.0 (/Users/chcl/Development/learning-rust/projects/stdin-debug)
    Finished dev [unoptimized + debuginfo] target(s) in 0.38s
     Running `target/debug/stdin-debug`
123
Parsed: 123

关于rust - 为什么在 Rust 中处理自定义错误类型时会出现运行错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64602325/

相关文章:

docker - 在 google cloud 上用 docker 构建一个 rust 项目非常慢

rust - 如何在 Rust 中创建一个 HashMap,其深度可以是映射值的 4 到 5 倍?

rust - 如何在Rust中解决此返回类型函数错误

rust - 在单独的文件中声明 map 并读取其内容

rust - 将函数和方法作为参数传递有什么区别?

asynchronous - 在 actix-web 中生成从多部分读取数据

rust - 为[u32; N]?

rust - 在 STDIN 之后编译然后对输入进行数学计算时出现不匹配的类型

rust - Option::map(FnOnce) 似乎不接受 FnOnce ...?

error-handling - 为什么 Arc::try_unwrap() 会引起 panic ?