亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Rust使用kind進(jìn)行異常處理(錯(cuò)誤的分類(lèi)與傳遞)

 更新時(shí)間:2022年09月27日 15:27:40   作者:微涼秋意  
Rust?有一套獨(dú)特的處理異常情況的機(jī)制,它并不像其它語(yǔ)言中的?try?機(jī)制那樣簡(jiǎn)單,這篇文章主要介紹了Rust指南錯(cuò)誤的分類(lèi)與傳遞以及使用kind進(jìn)行異常處理,需要的朋友可以參考下

前言

Rust 有一套獨(dú)特的處理異常情況的機(jī)制,它并不像其它語(yǔ)言中的 try 機(jī)制那樣簡(jiǎn)單。
在Rust 中的錯(cuò)誤分為兩大類(lèi):可恢復(fù)錯(cuò)誤和不可恢復(fù)錯(cuò)誤。大多數(shù)編程語(yǔ)言用 Exception (異常)類(lèi)來(lái)表示錯(cuò)誤。在 Rust 中沒(méi)有 Exception。對(duì)于可恢復(fù)錯(cuò)誤用 Result<T, E> 類(lèi)來(lái)處理,對(duì)于不可恢復(fù)錯(cuò)誤使用 panic! 宏來(lái)處理。

1、不可恢復(fù)錯(cuò)誤

  • 由編程中無(wú)法解決的邏輯錯(cuò)誤導(dǎo)致的,例如訪問(wèn)數(shù)組末尾以外的位置

1.1、panic! 宏的使用

的使用較為簡(jiǎn)單,讓我們來(lái)看一個(gè)具體例子:

fn main() {
    panic!("Error occured");
    println!("Hello, rust");
}

運(yùn)行結(jié)果:

很顯然,程序并不能如約運(yùn)行到 println!("Hello, rust") ,而是在 panic! 宏被調(diào)用時(shí)停止了運(yùn)行,不可恢復(fù)的錯(cuò)誤一定會(huì)導(dǎo)致程序受到致命的打擊而終止運(yùn)行。

1.2、通過(guò) Powershell命令行分析錯(cuò)誤原因

我們來(lái)分析一下終端命令行中的報(bào)錯(cuò)信息:

thread 'main' panicked at 'Error occured', src\main.rs:2:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

  • 第一行輸出了 panic! 宏調(diào)用的位置以及其輸出的錯(cuò)誤信息
  • 第二行是一句提示,翻譯成中文就是"通過(guò) RUST_BACKTRACE=full 環(huán)境變量運(yùn)行以顯示回溯"。

接下來(lái)看一下回溯(backtrace)信息:

stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library\std\src\panicking.rs:584
   1: core::panicking::panic_fmt
             at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library\core\src\panicking.rs:142
   2: error_deal::main
             at .\src\main.rs:2
   3: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3\library\core\src\ops\function.rs:248

回溯是不可恢復(fù)錯(cuò)誤的另一種處理方式,它會(huì)展開(kāi)運(yùn)行的棧并輸出所有的信息,然后程序依然會(huì)退出。通過(guò)大量的輸出信息,我們可以找到我們編寫(xiě)的 panic! 宏觸發(fā)的錯(cuò)誤。

2、可恢復(fù)的錯(cuò)誤

  • 如果訪問(wèn)一個(gè)文件失敗,有可能是因?yàn)樗诒徽加?,是正常的,我們可以通過(guò)等待來(lái)解決。

2.1、Rustlt<T,E>枚舉類(lèi)的使用

此概念十分類(lèi)似于 Java 編程語(yǔ)言中的異常,而在 C 語(yǔ)言中我們就常常將函數(shù)返回值設(shè)置成整數(shù)來(lái)表達(dá)函數(shù)遇到的錯(cuò)誤,在 Rust 中通過(guò) Result<T, E> 枚舉類(lèi)作返回值來(lái)進(jìn)行異常表達(dá):

enum Result<T, E> {
    Ok(T),
    Err(E),
}//T的類(lèi)型不定,相當(dāng)于C++中模板的寫(xiě)法

我們知道enum常常與match配合使用,當(dāng)匹配到OK時(shí)就會(huì)執(zhí)行相應(yīng)代碼。

在 Rust 標(biāo)準(zhǔn)庫(kù)中可能產(chǎn)生異常的函數(shù)的返回值都是 Result 類(lèi)型。

例如:當(dāng)我們嘗試打開(kāi)一個(gè)文件時(shí):

use std::fs::File;

fn main() {
    let fp = File::open("hello_rust.txt");
    match fp {
        Ok(file) => {
            println!("File opened successfully.");
        },
        Err(err) => {
            println!("Failed to open the file.");
        }
    }
}//OK里的參數(shù)file是File類(lèi)型,相當(dāng)于填充了枚舉里的T類(lèi)型

如果 hello_rust.txt 文件不存在,會(huì)打印 Failed to open the file.

當(dāng)然,我們?cè)诿杜e類(lèi)章節(jié)講到的 if let 模式匹配語(yǔ)法可以簡(jiǎn)化 match 語(yǔ)法塊:

use std::fs::File;

fn main() {
    let fp = File::open("hello_rust.txt");
    if let Ok(file) = fp {
        println!("File opened successfully.");
    } else {
        println!("Failed to open the file.");
    }
}

2.2、Result 類(lèi)的unwrap() 和 expect(message: &str) 方法

將一個(gè)可恢復(fù)錯(cuò)誤按不可恢復(fù)錯(cuò)誤處理

舉個(gè)例子:

use std::fs::File;

fn main() {
    let fp1 = File::open("hello_rust.txt").unwrap();
    let fp2 = File::open("hello_rust.txt").expect("Failed to open.");
}
  • 這段程序相當(dāng)于在 Result 為 Err 時(shí)調(diào)用 panic!宏
  • 兩者的區(qū)別在于 expect 能夠向 panic! 宏發(fā)送一段指定的錯(cuò)誤信息
  • panic!宏是不可恢復(fù)錯(cuò)誤,這樣就完成了轉(zhuǎn)變

3、可恢復(fù)的錯(cuò)誤的傳遞

之前所講的是接收到錯(cuò)誤的處理方式,接下來(lái)講講怎么把錯(cuò)誤信息傳遞出去

我們先來(lái)編寫(xiě)一個(gè)函數(shù):

fn f(i: i32) -> Result<i32, bool> {
    if i >= 0 {
         Ok(i) 
        }
    else { 
        Err(false) 
    }
}
fn main() {
    let r = f(10000);
    if let Ok(v) = r {
        println!("Ok: f(-1) = {}", v);
    } else {
        println!("Err");
    }
}//運(yùn)行結(jié)果:Ok: f(-1) = 10000

這里r的結(jié)果是f函數(shù)返回的ok(10000),經(jīng)過(guò)if let模式匹配后v的值為10000

這段程序中函數(shù) f 是錯(cuò)誤的根源,現(xiàn)在我們?cè)賹?xiě)一個(gè)傳遞錯(cuò)誤的函數(shù) g

fn g(i: i32) -> Result<i32, bool> {
    let t = f(i);
    return match t {
        Ok(i) => Ok(i),
        Err(b) => Err(b)
    };
}

函數(shù) g 傳遞了函數(shù) f 可能出現(xiàn)的錯(cuò)誤,這樣寫(xiě)有些冗長(zhǎng),Rust 中可以在 Result 對(duì)象后添加 ? 操作符將同類(lèi)的 Err 直接傳遞出去:

fn f(i: i32) -> Result<i32, bool> {
    if i >= 0 { Ok(i) }
    else { Err(false) }
}

fn g(i: i32) -> Result<i32, bool> {
    let t = f(i)?;
    Ok(t) // 因?yàn)榇_定 t 不是 Err, t 在這里已經(jīng)推導(dǎo)出是 i32 類(lèi)型
}

fn main() {
    let r = g(10000);
    if let Ok(v) = r {
        println!("Ok: g(10000) = {}", v);
    } else {
        println!("Err");
    }
}//運(yùn)行結(jié)果:Ok: g(10000) = 10000

? 符的實(shí)際作用是將 Result 類(lèi)非異常的值直接取出,如果有異常就將異常 Result 返回出去。所以? 符僅用于返回值類(lèi)型為 Result<T, E> 的函數(shù),且其中 E 類(lèi)型必須和 ? 所處理的 Result 的 E 類(lèi)型一致。

4、結(jié)合kind方法處理異常

雖然前面提到Rust 異常不像其他語(yǔ)言這么簡(jiǎn)單,但這并不意味著 Rust 實(shí)現(xiàn)不了:我們完全可以把 try 塊在獨(dú)立的函數(shù)中實(shí)現(xiàn),將所有的異常都傳遞出去解決。

實(shí)際上這才是一個(gè)分化良好的程序應(yīng)當(dāng)遵循的編程方法:應(yīng)該注重獨(dú)立功能的完整性。

但是這樣需要判斷 Result 的 Err 類(lèi)型,獲取 Err 類(lèi)型的函數(shù)是 kind()

做一個(gè)打開(kāi)文件的實(shí)例:

use std::io;
use std::io::Read;
use std::fs::File;

fn read_text_from_file(path: &str) -> Result<String, io::Error> {
    let mut f = File::open(path)?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

fn main() {
    let str_file = read_text_from_file("hello_rust.txt");
    match str_file {
        Ok(s) => println!("{}", s),
        Err(e) => {
            match e.kind() {
                io::ErrorKind::NotFound => {
                    println!("No such file");
                },
                _ => {
                    println!("Cannot read the file");
                }
            }
        }
    }
}//這里我沒(méi)有創(chuàng)建hello_rust.txt文件,因此運(yùn)行結(jié)果為:No such file

代碼解釋?zhuān)?/p>

  • 使用read_text_from_file()函數(shù)將文件打開(kāi)的結(jié)果傳給了str_file變量
  • 這里并不存在hello_rust.txt,因此File::open(path)?不會(huì)打開(kāi)文件,異常會(huì)存到f
  • f.read_to_string(&mut s)?并不能讀出文件內(nèi)容,ok(s)無(wú)內(nèi)容
  • 通過(guò)分析,分支會(huì)執(zhí)行Err(e)的代碼塊,使用e.kind()得到了錯(cuò)誤類(lèi)型并再次進(jìn)行match分支
  • 如果是NotFound錯(cuò)誤就會(huì)打印No such file
  • 其他情錯(cuò)誤均提示Cannot read the file

到此這篇關(guān)于Rust指南錯(cuò)誤的分類(lèi)與傳遞|使用kind進(jìn)行異常處理的文章就介紹到這了,更多相關(guān)Rust錯(cuò)誤處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何在Rust中處理命令行參數(shù)和環(huán)境變量

    如何在Rust中處理命令行參數(shù)和環(huán)境變量

    在本章節(jié)中, 我們探討了Rust處理命令行參數(shù)的常見(jiàn)的兩種方式和處理環(huán)境變量的兩種常見(jiàn)方式,感興趣的朋友一起看看吧
    2023-12-12
  • 使用vscode配置Rust運(yùn)行環(huán)境全過(guò)程

    使用vscode配置Rust運(yùn)行環(huán)境全過(guò)程

    VS Code對(duì)Rust有著較完備的支持,這篇文章主要給大家介紹了關(guān)于使用vscode配置Rust運(yùn)行環(huán)境的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 詳解在Rust語(yǔ)言中如何聲明可變的static類(lèi)型變量

    詳解在Rust語(yǔ)言中如何聲明可變的static類(lèi)型變量

    在Rust中,可以使用lazy_static宏來(lái)聲明可變的靜態(tài)變量,lazy_static是一個(gè)用于聲明延遲求值靜態(tài)變量的宏,本文將通過(guò)一個(gè)簡(jiǎn)單的例子,演示如何使用?lazy_static?宏來(lái)聲明一個(gè)可變的靜態(tài)變量,需要的朋友可以參考下
    2023-08-08
  • Rust動(dòng)態(tài)數(shù)組Vec基本概念及用法

    Rust動(dòng)態(tài)數(shù)組Vec基本概念及用法

    Rust中的Vec是一種動(dòng)態(tài)數(shù)組,它可以在運(yùn)行時(shí)自動(dòng)調(diào)整大小,本文主要介紹了Rust動(dòng)態(tài)數(shù)組Vec基本概念及用法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • 深入理解Rust中Cargo的使用

    深入理解Rust中Cargo的使用

    本文主要介紹了深入理解Rust中Cargo的使用,Cargo簡(jiǎn)化了項(xiàng)目的構(gòu)建過(guò)程,提供了依賴(lài)項(xiàng)管理,以及一系列方便的工作流程工具,下面就來(lái)具體的介紹一下如何使用,感興趣的可以了解一下
    2024-04-04
  • 一文詳解Rust中的錯(cuò)誤處理

    一文詳解Rust中的錯(cuò)誤處理

    這篇文章主要為大家詳細(xì)介紹了Rust中的錯(cuò)誤處理的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • 如何使用bindgen將C語(yǔ)言頭文件轉(zhuǎn)換為Rust接口代碼

    如何使用bindgen將C語(yǔ)言頭文件轉(zhuǎn)換為Rust接口代碼

    這篇文章主要介紹了使用bindgen將C語(yǔ)言頭文件轉(zhuǎn)換為Rust接口代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • rust中的match表達(dá)式使用詳解

    rust中的match表達(dá)式使用詳解

    在rust中提供了一個(gè)極為強(qiáng)大的控制流運(yùn)算符match,這篇文章主要介紹了rust中的match表達(dá)式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Rust 配置文件內(nèi)容及使用全面講解

    Rust 配置文件內(nèi)容及使用全面講解

    這篇文章主要為大家介紹了Rust 配置文件內(nèi)容及使用全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 如何用Rust打印hello world

    如何用Rust打印hello world

    這篇文章主要介紹了如何用Rust打印hello world,本文分步驟通過(guò)圖文并茂的形式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09

最新評(píng)論