📜  Rust恢复错误

📅  最后修改于: 2021-01-08 13:52:20             🧑  作者: Mango

锈迹恢复错误

  • 可恢复的错误是那些不会完全停止程序的错误。可以处理的错误称为可恢复错误。
  • 它由Result 表示。 Result 是一个包含两个变体的枚举,即OK 和Err 。它描述了可能的错误。

OK :'T'是一种值类型,在成功的情况下返回OK变量。这是预期的结果。

Err :'E'是一种错误类型,它在失败时返回ERR变量。这是出乎意料的结果。

 Enum Result
{
    OK,
    Err,
}
  • 在上述情况下,Result是枚举类型,而OK 和Err 是枚举类型的变体,其中“ T”“ E”是通用类型参数。
  • “ T”是在成功情况下将返回的值的类型,而“ E”是在失败情况下将返回的错误的类型。
  • 结果包含通用类型参数,因此我们可以在成功和失败值可能不同的许多不同情况下使用标准库中定义的结果类型和函数。

让我们看一个简单的示例,该示例返回Result值:

           use std::fs::File;
          fn main() 
         {
              let f:u32 = File::open("vector.txt");
         }

输出:

在上面的示例中,Rust编译器显示该类型不匹配。 'f'是u32类型,而File :: open返回Result 类型。上面的输出显示成功值的类型是std :: fs :: File,错误值的类型是std :: io :: Error。

注意:

  • File :: open的返回类型是成功值或失败值。如果file :: open成功,则返回文件句柄,如果file :: open失败,则返回错误值。结果枚举提供了此信息。
  • 如果File :: open success ,则f将具有包含文件句柄的OK变体,如果File :: open failed ,则f将具有Err变体,其中包含与错误有关的信息。

匹配表达式以处理结果变量。

让我们看一个简单的匹配表达式示例:

 use std::fs::File;
fn main()
 {
    let f = File::open("vector.txt");
    match f 
    {
        Ok(file) => file,
        Err(error) => {
        panic!("There was a problem opening the file: {:?}", error)
      },
    };
}

输出:

程序说明

  • 在上面的示例中,我们可以直接访问枚举变量,而无需在OKErr变量之前使用Result ::。
  • 如果结果为OK ,则它将返回文件并将其存储在'f'变量中。比赛结束后,我们可以在文件中执行读取或写入操作。
  • 比赛的第二臂根据Err值工作。如果Result返回Error值,则表示恐慌!运行并停止程序的执行。

对错误感到恐慌:unwrap()

  • Result 具有许多提供各种任务的方法。方法之一是unwrap()方法。 unwrap()方法是匹配表达式的快捷方式。 unwrap()方法和match表达式的工作方式相同。
  • 如果Result值是OK变量,则unwrap()方法将返回OK变量的值。
  • 如果Result值是Err变体,则unwrap()方法将引发恐慌!宏。

让我们看一个简单的例子:

 use std::fs::File;

fn main()
{
     File::open("hello.txt").unwrap();
}

输出:

在上面的示例中,unwrap()方法将自动调用panic宏和panic!显示错误信息。

对错误的恐慌:Expect()

  • Expect()方法的行为与unwrap()方法相同,即,这两种方法均会引起恐慌!显示错误信息。
  • Expect()和unwrap()方法之间的区别在于,错误消息将作为参数传递给Expect()方法,而unwrap()方法不包含任何参数。因此,可以说Expect()方法可以跟踪恐慌!来源更容易。

让我们看一个简单的Expect()例子

 use std::fs::File;
fn main()
{
     File::open("hello.txt").expect("Not able to find the file hello.txt");
}

输出:

在上面的输出中,错误消息显示在我们在程序中指定的输出屏幕上,即“无法找到文件hello.txt ”,这使我们更容易从错误发生的地方查找代码。从。如果我们包含多个unwrap()方法,那么很难找到unwrap()方法引起恐慌的地方!一样惊慌!对所有错误显示相同的错误消息。

传播错误

传播错误是一种将错误从一个函数转发到另一函数。错误会传播到调用函数,在调用函数中可以获取更多信息,以便可以处理错误。假设我们有一个名为“ a.txt”的文件,其中包含文本“ javaTpoint”。我们要创建一个对该文件执行读取操作的程序。让我们来研究这个例子

让我们看一个简单的例子:

 use std::io;
use std::io::Read;
use std::fs::File;
fn main()
{
  let a = read_username_from_file();
  print!("{:?}",a);
}
fn read_username_from_file() -> Result 
{
    let f = File::open("a.txt");
    let mut f = match f {
    Ok(file) => file,
    Err(e) => return Err(e),
    };
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

输出:

程序说明

  • read_username_from_file()函数返回Result 类型的值,其中'T'是字符串类型,'E'是io:Error类型。
  • 如果函数成功,则返回包含字符串的OK值,如果函数失败,则返回Err值。
  • 此函数通过调用File :: open函数。如果File :: open函数失败,则比赛的第二臂将返回Err值;如果File :: open函数成功,则它将文件句柄的值存储在变量f中。
  • 如果File :: open函数成功,则我们将创建一个String变量。如果read_to_string()方法成功,则它返回文件的文本,否则返回错误信息。
  • 假设我们有一个名为“ a.text”的外部文件,其中包含文本“ javaTpoint”。因此,此程序读取文件'a.text'并显示文件的内容。

传播错误的捷径:“?”运算符

指某东西的用途 '?'运算符可减少代码的长度。 '?'运算符是替换匹配表达式表示“?”运算符的工作方式与匹配表达式的工作方式相同。假设我们有一个名为“ a.txt”的文件,其中包含文本“ javaTpoint”。我们要创建一个对该文件执行读取操作的程序。让我们来研究这个例子

让我们看一个简单的例子。

 use std::io;
use std::io::Read;
use std::fs::File;
fn main()
{
  let a = read_username_from_file();
  print!("{:?}",a);
}
fn read_username_from_file() -> Result 
{
   let mut f = File::open("a.txt")?;
   let mut s = String::new();
   f.read_to_string(&mut s)?;
  Ok(s)
}

输出:

在上面的示例中,“?”在“结果”值类型之前使用运算符。如果Result是OK,则返回OK变量的值,如果Result是Err,则返回错误信息。

黑白差异'?'运算符和匹配表达式

  • 与“?”一起使用的错误通过“从”“从”函数的函数和运算符的移动在在标准库中定义的从性状。
  • 当。。。的时候 '?'运算符调用'from'函数,然后此函数将错误类型转换为在当前函数的返回类型中定义的错误类型。
  • 如果没有错误发生,则为“?”任何函数结尾的运算符都将返回OK的值,如果发生错误,则返回Err的值。
  • 它使函数的实现更简单。

链接方法在“?”之后调用运算符

我们甚至可以通过在'?'之后使用链接方法调用来进一步缩短程序代码。运算符。

让我们看一个简单的例子:

 use std::io;
use std::io::Read;
use std::fs::File;
fn main()
{
  let a = read_username_from_file();
  print!("{:?}",a);
}
fn read_username_from_file() -> Result 
{
    let mut s = String::new();
   File::open("a.txt")?.read_to_string(&mut s)?;
   Ok(s)
}

输出:

程序说明

在上面的示例中,我们将read_to_string()的调用链接到File :: open(“ a.txt”)?的调用结果。我们将'?' read_to_string()调用结束时的运算符。如果两个函数(即read_to_string()和File :: open(“ a.txt”))都成功,则返回OK值,否则返回错误值。

'?'的局限性运算符

'?'运算符只能在返回Result类型值的函数中使用。作为“?”运算符的作用类似于匹配表达式。 match表达式仅适用于Result返回类型。

让我们通过一个简单的例子来理解这一点。

 use std::fs::File;
fn main() 
{
    let f = File::open("a.txt")?;
}

输出: