日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

入門Rust的固定套路:錯誤處理模式有三大類,幫你總結了

來源: 責編: 時間:2023-12-20 17:47:22 280觀看
導讀最近在學習總結Rust的各種場景的語法模式,也就是Rust寫代碼的模式。今天分享關于Rust的錯誤處理的三大類語法模式。先列出一個大綱第一類:有意不處理錯誤,忽略錯誤unwrap().fn( )? 符號,代替rust早期版本中的try!宏第二類

最近在學習總結Rust的各種場景的語法模式,也就是Rust寫代碼的模式。5NW28資訊網——每日最新資訊28at.com

今天分享關于Rust的錯誤處理的三大類語法模式。5NW28資訊網——每日最新資訊28at.com

5NW28資訊網——每日最新資訊28at.com

先列出一個大綱

第一類:有意不處理錯誤,忽略錯誤5NW28資訊網——每日最新資訊28at.com

  • unwrap()
  • .fn( )? 符號,代替rust早期版本中的try!宏

第二類:對錯誤做自定義信息提示5NW28資訊網——每日最新資訊28at.com

  • 使用expect()。

第三類:推薦!根據正確和錯誤情況分開處理,錯誤還可以進一步分流處理5NW28資訊網——每日最新資訊28at.com

  • match(包括 match處理 Result<T,E>或  match處理Option<>, 或 使用map_err())
  • 使用if let Some(value)= fn() {} else {}
  • 使用特定的函數:and_then() 和 or_else()

我對Rust的錯誤處理的印象

Rust的錯誤處理方式比起Golang更靈活,可以針對錯誤和當下代碼需要賦值前做錯誤判斷、故意忽略異常、異常時打印錯誤并終止等的不同編碼場景,選用不同的語法模式。5NW28資訊網——每日最新資訊28at.com

錯誤處理涉及到數據類型、錯誤處理的控制語法、相關的crate模塊。5NW28資訊網——每日最新資訊28at.com

Rust錯誤處理涉及到的數據類型

錯誤處理的類型1:Result

Result屬于Rust的核心crate提供的功能(core::result::Result)。Result 有2個特點:5NW28資訊網——每日最新資訊28at.com

首先,Result<T,E> 屬于泛型,所以T和E可以是任意類型。但常見的使用模式是以T存儲正常情況的信息,E存儲錯誤和異常情況的信息。5NW28資訊網——每日最新資訊28at.com

其次,Result是枚舉類型,其內部實際只包含:5NW28資訊網——每日最新資訊28at.com

Ok()Err()

這兩個枚舉,所以它的實例只會是Ok()或Err()之一。5NW28資訊網——每日最新資訊28at.com

Result的代碼實現中就用的枚舉類型的,代碼如下:5NW28資訊網——每日最新資訊28at.com

/// Result的定義在 rust核心代碼 src/rust/library/core/src/result.rs 代碼文件中:/// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).////// See the [module documentation](self "module documentation") for details.#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]#[must_use = "this `Result` may be an `Err` variant, which should be handled"]#[rustc_diagnostic_item = "Result"]#[stable(feature = "rust1", since = "1.0.0")]pub enum Result<T, E> {    /// Contains the success value    #[lang = "Ok"]    #[stable(feature = "rust1", since = "1.0.0")]    Ok(#[stable(feature = "rust1", since = "1.0.0")] T),    /// Contains the error value    #[lang = "Err"]    #[stable(feature = "rust1", since = "1.0.0")]    Err(#[stable(feature = "rust1", since = "1.0.0")] E),}

實際使用的一個例子:例如Result<String, &str> 是一個泛型類型,則此時的T類型為String,E類型為&str。它表示一個可能成功或失敗的操作的結果,其中成功時的返回類型為 String,失敗時的錯誤類型為 &str。5NW28資訊網——每日最新資訊28at.com

總結一下Result<Ok(),Err()>:  result 類型通常用于表示可能成功或失敗的操作的結果。它使用 Result<T, E> 類型來表示,其中 T 是成功時的返回類型,E 是失敗時的錯誤類型。5NW28資訊網——每日最新資訊28at.com

錯誤處理的類型2:Option

Option也是枚舉類型,其內部實際只包含兩種值:Some()和None,這個可以從其代碼中得到印證。Option的實現代碼為:5NW28資訊網——每日最新資訊28at.com

/// 代碼文件 rustlib/src/rust/library/core/src/option.rs 定義了Option/// The `Option` type. See [the module level documentation](self "the module level documentation") for more.#[derive(Copy, PartialOrd, Eq, Ord, Debug, Hash)]#[rustc_diagnostic_item = "Option"]#[lang = "Option"]#[stable(feature = "rust1", since = "1.0.0")]pub enum Option<T> {    /// No value.    #[lang = "None"]    #[stable(feature = "rust1", since = "1.0.0")]    None,    /// Some value of type `T`.    #[lang = "Some"]    #[stable(feature = "rust1", since = "1.0.0")]    Some(#[stable(feature = "rust1", since = "1.0.0")] T),}

Result 和 Option 有什么區別?

首先,從名稱上理解一下:5NW28資訊網——每日最新資訊28at.com

  • Result 中文意思是結果。一般表示成功或失敗,所以它的枚舉值會是Ok()和Err();
  • Option,中文意思是選項。那么它的側重點不是成功失敗,而是不同的選項(有選項則為Some()、無選項則為None),所以它的枚舉值也很清楚,只有Some()和None兩個值。

其次,它們之間可以互相轉化。對于錯誤處理來說,match處理Result或Option時,都要處理錯誤或None等異常值,就實現了Rust的最重要的錯誤處理邏輯。5NW28資訊網——每日最新資訊28at.com

錯誤處理的控制語法的具體分析和舉例

1.Rust的第一類錯誤處理模式:忽略錯誤,不處理錯誤:

(1) unwrap()5NW28資訊網——每日最新資訊28at.com

在 Rust 中,unwrap() 方法用于從 Result 類型中提取成功時的返回值。如果 Result 類型的值是 Ok(表示成功),則 unwrap() 方法將返回 T;如果 Result 類型的值是 Err(表示失敗),則 unwrap() 方法將觸發一個 panic,拋出一個 E 類型的錯誤。如果您在調用 unwrap() 方法時遇到錯誤,說明您正在處理一個 Err 類型的值,即失敗的情況。在這種情況下,您應該使用其他方法來處理錯誤,而不是直接使用 unwrap() 方法。總之,在處理 Result 類型時,應該始終考慮可能的失敗情況,并使用適當的方法來處理錯誤。直接使用 unwrap() 方法可能會導致程序崩潰(panic),因此應該謹慎使用。只應該在非生產的代碼中使用。5NW28資訊網——每日最新資訊28at.com

(2) .fn()?符號5NW28資訊網——每日最新資訊28at.com

這個符號在Rust中的術語是“提前返回選項”(early return option),作用等同于unwrap()。只允許用于返回Result<>或Option<>類型的函數之后。在rust的早期版本中,有個try!宏具有等效的功能。5NW28資訊網——每日最新資訊28at.com

代碼演示:(演示打開文件,返回Result<File, Error> 類型的值,然后可以被main()中的match方式處理):5NW28資訊網——每日最新資訊28at.com

use std::fs::File;use std::io::Error;fn open_file(file_path: &str) -> Result<File, Error> {    let mut file = File::open(file_path)?;    Ok(file)    }

這段函數內部使用File::open(file_path)?; 打開指定路徑的文件,open()是rust的內部函數,原始定義為:5NW28資訊網——每日最新資訊28at.com

pub fn open<P>(path: P) -> io::Result<File>

而演示代碼中有意忽略了錯誤的情況,以?結尾,來調用open()函數:5NW28資訊網——每日最新資訊28at.com

let mut file = File::open(file_path)?;

2.Rust的第二類錯誤處理模式:對錯誤做自定義信息提示:

expect() 可作為代替unwrap()或 ? 相比unwrap(), expect()是一個更好的選擇,因為它允許發生錯誤時打印一個簡單的消息并終止運行。5NW28資訊網——每日最新資訊28at.com

3.Rust的第三類錯誤處理模式(推薦!):

根據正確和錯誤情況分開處理,錯誤還可以進一步分流處理。5NW28資訊網——每日最新資訊28at.com

(1) match,根據正確和錯誤情況分開處理。5NW28資訊網——每日最新資訊28at.com

  • 使用match 分流處理 Result<T,E>中包含錯誤的情況處理:
use std::fs::File;use std::io::Error;/// 演示打開文件,返回Result<File, Error> 類型的值,然后被main()中的match方式處理fn open_file(file_path: &str) -> Result<File, Error> {    let mut file = File::open(file_path)?;    Ok(file)}fn main() {    let file_path = "file.txt";    let file = open_file(file_path);    match file {        Ok(file) => println!("文件打開成功 {:?}", file),        Err(error) => println!("文件打開失敗 {}", error),    }}
  • 使用 match 分流處理 Option<>包含錯誤的情況處理:
use std::fs::File;use std::io::ErrorKind;use std::io::{Error, Read};/// 演示文件打開時 如何返回Option<T> 類型值fn open_file(file_path: &str) -> Option<File> {    let mut file = File::open(file_path).unwrap();    Some(file)}/// 演示 match 如何處理 Option<T> 類型值,其中有None類型的情況fn read_file(file: Option<File>) -> Result<String, Error> {    match file {        //處理文件的正常情況        Some(mut file) => {            let mut buffer = String::new();            let file_content = file.read_to_string(&mut buffer);            Ok(buffer)        }        //處理文件的異常情況        None => Err(Error::new(ErrorKind::NotFound, "File not found")),    }}fn main() {    let file_path = "file.txt";    let file = open_file(&file_path);    let strings_in_file = read_file(file);    /// 在文件 file.txt 不存在的情況下,以下代碼會導致軟件崩潰。    println!("{}", strings_in_file.unwrap());    ///echo "1111">> file.txt    /// 創建 file.txt文件    /// 然后重復上面代碼}
  • 使用 map_err() 鏈式處理

map_err()  將在以后發布的文章中再講解。本文不做詳細介紹。5NW28資訊網——每日最新資訊28at.com

(2) if let,適合直接在賦值前做錯誤處理。代碼模式為:5NW28資訊網——每日最新資訊28at.com

let  final_value = if let Some(T) = Rust語句 {    //語句正確和成功的情況,如獲取有效數據,將作為作用域的返回值賦值給final_value } else {    //錯誤或異常的情況的處理,如賦值為"",同樣會作為作用域的返回值賦值給 final_value }

以下是一些常見的處理錯誤的方法:使用 match 表達式:通過使用 match 表達式,您可以根據 Result 類型的值來執行不同的操作。如果是 Ok 類型,可以提取成功的值;如果是 Err 類型,可以處理錯誤。使用 map_err() 方法:map_err() 方法可以將 Err 類型的值轉換為另一種錯誤類型,并返回一個新的 Result 類型。使用 and_then() 或 or_else() 方法:這些方法可以在成功或失敗的情況下執行不同的操作,并返回一個新的 Result 類型。5NW28資訊網——每日最新資訊28at.com

(3) 使用特定的函數:and_then() 和 or_else()和 ok_or()5NW28資訊網——每日最新資訊28at.com

這3個函數在Rust中的術語為組合算子,如果你已理解C/C++中的 && 和 ||或 Python中的and以及or語法的意義,那么你大概已經理解了 and_then() 這3個函數的意思。比如 and_then()是當調用者為true或調用者為正常的時候,才會調用and_then(...)函數。那么對于錯誤處理就非常有用。5NW28資訊網——每日最新資訊28at.com

下面的代碼例子演示了烹飪的邏輯:當有食材的時候,才能按照食譜制作好菜品。隱含的意思就是(錯誤的情況下),沒有食材的情況下,就不用照著食譜做菜了。5NW28資訊網——每日最新資訊28at.com

#![allow(dead_code)]#[derive(Debug)] enum Food { CordonBleu, Steak, Sushi }#[derive(Debug)] enum Day { Monday, Tuesday, Wednesday }// 我們沒有原材料(ingredient)來制作壽司。fn have_ingredients(food: Food) -> Option<Food> {    match food {        Food::Sushi => None,        _           => Some(food),    }}// 我們擁有全部食物的食譜,除了欠缺高超的烹飪手藝。fn have_recipe(food: Food) -> Option<Food> {    match food {        Food::CordonBleu => None,        _                => Some(food),    }}// 做一份好菜,我們需要原材料和食譜這兩者。// 我們可以借助一系列 `match` 來表達相應的邏輯:// (原文:We can represent the logic with a chain of `match`es:)fn cookable_v1(food: Food) -> Option<Food> {    match have_ingredients(food) {        None       => None,        Some(food) => match have_recipe(food) {            None       => None,            Some(food) => Some(food),        },    }}// 這可以使用 `and_then()` 方便重寫出更緊湊的代碼:fn cookable_v2(food: Food) -> Option<Food> {    have_ingredients(food).and_then(have_recipe)}fn eat(food: Food, day: Day) {    match cookable_v2(food) {        Some(food) => println!("Yay! On {:?} we get to eat {:?}.", day, food),        None       => println!("Oh no. We don't get to eat on {:?}?", day),    }}fn main() {    let (cordon_bleu, steak, sushi) = (Food::CordonBleu, Food::Steak, Food::Sushi);    eat(cordon_bleu, Day::Monday);    eat(steak, Day::Tuesday);    eat(sushi, Day::Wednesday);}

本文鏈接:http://www.www897cc.com/showinfo-26-50775-0.html入門Rust的固定套路:錯誤處理模式有三大類,幫你總結了

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 系統設計小抄 - 如何做到高可用、高吞吐、高擴展性

下一篇: 用了這個庫,真的可以丟掉任務管理器了

標簽:
  • 熱門焦點
  • 小米官宣:2023年上半年出貨量中國第一!

    今日早間,小米電視官方微博帶來消息,稱2023年小米電視上半年出貨量達到了中國第一,同時還表示小米電視的巨屏風暴即將開始。“公布一個好消息2023年#小米電視上半年出貨量中國
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實現手段有以下幾種方式:Object 類下
  • 一篇文章帶你了解 CSS 屬性選擇器

    屬性選擇器對帶有指定屬性的 HTML 元素設置樣式。可以為擁有指定屬性的 HTML 元素設置樣式,而不僅限于 class 和 id 屬性。一、了解屬性選擇器CSS屬性選擇器提供了一種簡單而
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • iQOO Neo8 Pro即將開售:到手價3099元起 安卓性能最強旗艦

    5月23日,iQOO如期舉行了新品發布會,全新的iQOO Neo8系列也正式與大家見面,包含iQOO Neo8和iQOO Neo8 Pro兩個版本,其中標準版搭載高通驍龍8+,而Pro版更
  • Android 14發布:首批適配機型公布

    5月11日消息,谷歌在今天凌晨舉行了I/O大會,本次發布會谷歌帶來了自家的AI語言模型PaLM 2、谷歌Pixel Fold折疊屏、谷歌Pixel 7a手機,同時發布了Androi
  • iQOO Neo8 Pro真機諜照曝光:天璣9200+和V1+旗艦雙芯加持

    去年10月,iQOO推出了iQOO Neo7系列機型,不僅搭載了天璣9000+,而且是同價位唯一一款天璣9000+直屏旗艦,一經上市便受到了用戶的廣泛關注。在時隔半年后,
  • 英特爾Xe-HP項目終止,將專注Xe-HPC/HPG系列顯卡

    據10 月 31 日消息報道,英特爾高級副總裁兼加速計算系統和圖形事業部總經理 表示,Xe-HP“ Arctic Sound” 系列服務器 GPU 已經應用于 oneAPI devcloud 云服
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 垫江县| 郓城县| 高尔夫| 漾濞| 安塞县| 阜平县| 兰坪| 五莲县| 枣强县| 梓潼县| 吉林省| 嘉峪关市| 进贤县| 永新县| 涿州市| 诸暨市| 宁乡县| 盐城市| 遂溪县| 汉阴县| 太保市| 丹江口市| 胶州市| 平顶山市| 隆子县| 夹江县| 义马市| 翼城县| 昌平区| 平乡县| 麻城市| 晋中市| 新余市| 石泉县| 平度市| 邛崃市| 布尔津县| 巫山县| 云林县| 廊坊市| 武汉市|