这个问题在这里已经有了答案:
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 ?
简短的回答是,如果 Result
是 Ok
,然后 .expect()
将展开并返回 Ok
中包含的值元组结构。如果 Result
是 Err
,然后 .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/