Rust可恢复错误处理实例分析

本文概述

  • 可恢复的错误是那些不太严重以至于无法完全停止程序的错误。可以处理的错误称为可恢复错误。
  • 它由Result <T, E>表示。 Result <T, E>是一个包含两个变体的枚举, 即OK <T>和Err <E>。它描述了可能的错误。

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

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

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

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

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

输出

Rust可恢复错误

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

注意:

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

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

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

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)
      }, };
}

输出

Rust可恢复错误

程序说明

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

对错误感到恐慌:unwrap()

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

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

use std::fs::File;

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

输出

Rust可恢复错误

在上面的示例中, 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");
}

输出

Rust可恢复错误

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

传播错误

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

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

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<String, io::Error> 
{
    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), }
}

输出

Rust可恢复错误

程序说明

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

传播错误的捷径:”?”算子

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

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

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<String, io::Error> 
{
   let mut f = File::open("a.txt")?;
   let mut s = String::new();
   f.read_to_string(&mut s)?;
  Ok(s)
}

输出

Rust可恢复错误

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

黑白相差’?’运算符和匹配表达式

  • 与”?”一起使用的错误操作符在” from”函数中移动, 并且” from”函数在标准库的from trait中定义。
  • 当。。。的时候 ‘?’操作员调用” 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<String, io::Error> 
{
    let mut s = String::new();
   File::open("a.txt")?.read_to_string(&mut s)?;
   Ok(s)
}

输出

Rust可恢复错误

程序说明

在上面的示例中, 我们将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")?;
}

输出

Rust可恢复错误

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?