在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

rust語(yǔ)言基礎(chǔ)學(xué)習(xí): rust中的錯(cuò)誤處理

冬至子 ? 來(lái)源:山川與湖水 ? 作者:山川與湖水 ? 2023-05-22 16:28 ? 次閱讀

錯(cuò)誤是軟件中不可避免的,所以 Rust 有一些處理出錯(cuò)情況的特性。在許多情況下,Rust 要求你承認(rèn)錯(cuò)誤的可能性,并在你的代碼編譯前采取一些行動(dòng)。這一要求使你的程序更加健壯,因?yàn)樗梢源_保你在將代碼部署到生產(chǎn)環(huán)境之前就能發(fā)現(xiàn)錯(cuò)誤并進(jìn)行適當(dāng)?shù)奶幚怼?/p>

Rust中的錯(cuò)誤可分為可 恢復(fù)錯(cuò)誤 (recoverable)和 不可恢復(fù)錯(cuò)誤 (unrecoverable)

可恢復(fù)錯(cuò)誤代表一種可以恢復(fù)的情況下失敗,可以向用戶(hù)報(bào)告問(wèn)題并重試操作,例如未找到文件;

不可恢復(fù)錯(cuò)誤代表一種不可處理的狀態(tài),會(huì)導(dǎo)致程序 崩2 ,例如嘗試訪問(wèn)超過(guò)數(shù)組結(jié)尾的位置;

對(duì)比其他編程語(yǔ)言的錯(cuò)誤處理:
1. Java語(yǔ)言采用了異常機(jī)制的方式來(lái)處理,并沒(méi)有明確區(qū)分可恢復(fù)錯(cuò)誤和不可恢復(fù)錯(cuò)誤。
(ps: 雖然Java的異常給出了Throwable, Error, Exception, RuntimeException的
繼承關(guān)系體系,異常分為checked exception和uncheced exceppion,但在異常傳播上
采用的是通過(guò)棧回溯的方式一層層傳遞,直到出現(xiàn)捕獲異常的地方。) Java語(yǔ)言這種異常
處理方式的優(yōu)點(diǎn)是簡(jiǎn)化了錯(cuò)誤處理流程,但在運(yùn)行時(shí)開(kāi)銷(xiāo)比使用返回值返回錯(cuò)誤信息的方式要大很多。
2. Go語(yǔ)言是明確區(qū)分可恢復(fù)錯(cuò)誤(error)和不可恢復(fù)錯(cuò)誤(panic)的。Go對(duì)可恢復(fù)錯(cuò)誤
采用了以函數(shù)返回錯(cuò)誤值的形式,在函數(shù)返回時(shí)額外返回一個(gè)錯(cuò)誤對(duì)象(error),這種方式的優(yōu)點(diǎn)
是錯(cuò)誤處理的運(yùn)行時(shí)開(kāi)銷(xiāo)小,缺點(diǎn)是返回的錯(cuò)誤必須處理或者顯式傳播返回給上級(jí)調(diào)用,
因此一個(gè)Go程序代碼中會(huì)有大量的if err!= nil {return err;}。

Rust中沒(méi)有異常,對(duì)于可恢復(fù)錯(cuò)誤使用了類(lèi)型Result,即函數(shù)返回的錯(cuò)誤信息通過(guò)類(lèi)型系統(tǒng)描述。對(duì)于在程序遇到不可恢復(fù)的錯(cuò)誤時(shí)panic!時(shí)停止執(zhí)行

1. Result和可恢復(fù)錯(cuò)誤

Result是一個(gè)枚舉類(lèi)型,其定義如下:

#[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_type"]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Result

Result枚舉有兩個(gè)成員,OkErrTE是泛型參數(shù),T代表成功返回的Ok成員中的數(shù)據(jù)類(lèi)型。E代表失敗返回的Err成員中的錯(cuò)誤的類(lèi)型。有了這兩個(gè)泛型參數(shù),可以將Result枚舉作為函數(shù)的返回值,用于各種場(chǎng)景下的可恢復(fù)錯(cuò)誤的處理,當(dāng)函數(shù)成功時(shí)返回Ok(T),失敗時(shí)返回Err(E)

Result的定義上面有一個(gè)must_use的標(biāo)注,rust的編譯器會(huì)對(duì)must_use標(biāo)注的類(lèi)型做特殊處理,如果該類(lèi)型對(duì)應(yīng)的值沒(méi)有被顯式使用,則就會(huì)有一個(gè)警告。例如下面的代碼。

fn foo() -> Result<(), String> {
    Ok(())
}


fn main() {
    foo(); // unused `std::result::Result` that must be used
}

代碼在調(diào)用foo函數(shù)時(shí),忽略了返回值Result,因?yàn)镽esult上有must_use標(biāo)注,所以Rust的編譯器在編譯時(shí)會(huì)報(bào)一個(gè)警告:

warning: unused `Result` that must be used
 --> src/main.rs:7:5
  |
7 |     foo(); // unused `std::result::Result` that must be used
  |     ^^^^^^
  |
  = note: `#[warn(unused_must_use)]` on by default
  = note: this `Result` may be an `Err` variant, which should be handled

1.1 匹配不同的錯(cuò)誤原因

在處理錯(cuò)誤時(shí),很多時(shí)候需要針對(duì)不同的錯(cuò)誤原因進(jìn)行不同的處理。下面來(lái)學(xué)習(xí)一下rust標(biāo)準(zhǔn)庫(kù)中的std::io module中是如何設(shè)計(jì)錯(cuò)誤處理的。

std::io中定義了一個(gè)std::io::Result:

#[stable(feature = "rust1", since = "1.0.0")]
pub type Result

io::Result的定義可以看出,io::Result實(shí)際上是result::Result的別名。 io::Result中的Err成員類(lèi)型是io::Error

io::Error是一個(gè)結(jié)構(gòu)體,它由一個(gè)kind()方法簽名是pub fn kind(&self) -> ErrorKind,返回描述錯(cuò)誤原因枚舉ErrorKind

ErrorKind的成員是各種io錯(cuò)誤原因,比如NotFound, PermissionDenied

因此如果函數(shù)返回io::Result,失敗時(shí)返回的是io::Error時(shí),就可以調(diào)用kind方法,進(jìn)一步匹配不同的錯(cuò)誤原因進(jìn)行不同處理。

use std::fs::File;
use std::io::ErrorKind;


fn main() {
    let f = File::open("hello.txt").unwrap_or_else(|err| {
        match err.kind() {
            ErrorKind::NotFound => File::create("hello.tx").unwrap_or_else(|error| {
                panic!("Problem creating the file: {:?}", error);
            }), // 匹配錯(cuò)誤原因, 對(duì)于文件不存在的錯(cuò)誤處理為創(chuàng)建文件
            other_error_kind => panic!("Problem opening the file: {:?}", other_error_kind)
        }
    });
    println!("{:?}", f);
}

例2中還用到了Result的unwrap_or_else方法,Result類(lèi)型定義了很多輔助方法來(lái)處理各種情況。除了unwrap_or_else外,還有:

  • unwrap方法: 如果Result的值是成員Okunwrap就返回Ok的值;如果Result的值是成員Errunwrap就會(huì)調(diào)用panic!
  • expect方法: 與unwrap的使用方式一樣,允許我們傳參指定panic!的信息

1.2 使用?操作符傳播錯(cuò)誤

經(jīng)常在編寫(xiě)一個(gè)函數(shù)實(shí)現(xiàn)時(shí)會(huì)調(diào)用另一個(gè)返回Result的函數(shù),除了在這個(gè)函數(shù)中處理錯(cuò)誤之外,還可以選擇將錯(cuò)誤傳播到上游調(diào)用者,這就是傳播錯(cuò)誤。

rust還提供了強(qiáng)大的?操作符,如果我們只想要傳播錯(cuò)誤,而不想直接處理,可以使用?操作符。

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


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

代碼中第6行的?操作符會(huì)被展開(kāi)成類(lèi)似下面的代碼:

match result {
    Ok(v) => v,
    Err(e) => Err(e.into())
}
```Result 值之后的 ? 作用為與 match 表達(dá)式有著完全相同的工作方式。如果 Result 的值是 Ok,這個(gè)表達(dá)式將會(huì)返回 Ok 中的值而程序?qū)⒗^續(xù)執(zhí)行。如果值是 ErrErr 中的值將作為整個(gè)函數(shù)的返回值,就好像使用了 return 關(guān)鍵字一樣,這樣錯(cuò)誤值就被傳播給了調(diào)用者。

match 表達(dá)式與 ? 運(yùn)算符所做的有一點(diǎn)不同:? 運(yùn)算符所使用的錯(cuò)誤值被傳遞給了 from 函數(shù),它定義于標(biāo)準(zhǔn)庫(kù)的 From trait 中,其用來(lái)將錯(cuò)誤從一種類(lèi)型轉(zhuǎn)換為另一種類(lèi)型。當(dāng) ? 運(yùn)算符調(diào)用 from 函數(shù)時(shí),收到的錯(cuò)誤類(lèi)型被轉(zhuǎn)換為由當(dāng)前函數(shù)返回類(lèi)型所指定的錯(cuò)誤類(lèi)型。

## 2. panic! 和不可恢復(fù)錯(cuò)誤

突然有一天,代碼出問(wèn)題了,程序崩潰,對(duì)于這種情況,Rust提供了一個(gè)panic!宏,當(dāng)執(zhí)行這個(gè)宏時(shí),程序會(huì)打印出一個(gè)錯(cuò)誤信息,展開(kāi)并清理?xiàng)?shù)據(jù),然后接著退出。出現(xiàn)這種情況的場(chǎng)景通常是檢測(cè)到一些類(lèi)型的 bug,Rust程序員可以讓 Rust 在 panic 發(fā)生時(shí)打印調(diào)用堆棧(call stack)以便于定位 panic 的原因。

在實(shí)踐中有兩種方法造成 panic:

* 執(zhí)行會(huì)造成代碼 panic 的操作,比如訪問(wèn)超過(guò)數(shù)組結(jié)尾的內(nèi)容
* 顯式調(diào)用 panic! 宏,比如`panic!("crash and burn");`。

panic!表示不可恢復(fù)的錯(cuò)誤,希望程序馬上終止運(yùn)行并得到崩潰信息。

rust標(biāo)準(zhǔn)庫(kù)還提供了`catch_unwind()`,可以把panic的調(diào)用棧回溯到catch_unwind的時(shí)候。

use std::panic;

fn main() {

let result = panic::catch_unwind(|| {

panic!("crash");

});

if result.is_err() {

println!("panic reover: {:#?}", result);

}

println!("exit ok!");

}

代碼運(yùn)行結(jié)果如下:

thread 'main' panicked at 'crash', src/main.rs:4:9

note: run with RUST_BACKTRACE=1 environment variable to display

a backtracepanic reover: Err(

Any { .. },

)

exit ok!

### 2.1 使用 `panic!` 的 backtrace

可以使用 `RUST_BACKTRACE=1 cargo run` 來(lái)得到一個(gè) backtrace,backtrace 是一個(gè)執(zhí)行到目前位置所有被調(diào)用的函數(shù)的列表。Rust 的 backtrace 跟其他語(yǔ)言中的一樣:閱讀 backtrace 的關(guān)鍵是從頭開(kāi)始讀直到發(fā)現(xiàn)你編寫(xiě)的文件。這就是問(wèn)題的發(fā)源地。這一行往上是你的代碼所調(diào)用的代碼;往下則是調(diào)用你的代碼的代碼。這些行可能包含核心 Rust 代碼,標(biāo)準(zhǔn)庫(kù)代碼或用到的 crate 代碼。

// src/main.rs

fn main() {

let v = vec![1, 2, 3];

v[99];

}

$ RUST_BACKTRACE=1 cargo run

thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5

stack backtrace:

0: rust_begin_unwind at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:584:5

1: core::panicking::panic_fmt at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/panicking.rs:142:14

2: core::panicking::panic_bounds_check at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/panicking.rs:84:5

3: >::index at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/slice/index.rs:242:10

4: core::slice::index:: for [T]>::index at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/slice/index.rs:18:9

5: [alloc::vec::Vec as core::ops::index::Index*>::index at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/alloc/src/vec/mod.rs:2591:9

6: panic::main at ./src/main.rs:4:5

7: core::ops::function::FnOnce::call_once at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/ops/function.rs:248:5

note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.*](alloc::vec::Vec%3CT,A)

[**

## 總結(jié)

Rust 的錯(cuò)誤處理功能被設(shè)計(jì)為幫助你編寫(xiě)更加健壯的代碼。`panic!` 宏代表一個(gè)程序**無(wú)法處理**的狀態(tài),并停止執(zhí)行而不是使用無(wú)效或不正確的值繼續(xù)處理。Rust 類(lèi)型系統(tǒng)的 `Result` 枚舉代表操作可能會(huì)在一種**可以恢復(fù)**的情況下失敗,可以使用 `Result` 來(lái)告訴代碼調(diào)用者他需要處理潛在的成功或失敗。在適當(dāng)?shù)膱?chǎng)景使用 `panic!``Result` 將會(huì)使你的代碼在面對(duì)不可避免的錯(cuò)誤時(shí)顯得更加可靠。

* 可恢復(fù)錯(cuò)誤:想向用戶(hù)報(bào)告問(wèn)題并**重試**操作,Result處理;
* 不可恢復(fù)錯(cuò)誤:導(dǎo)致程序**崩潰的**panic,catch_unwind() 棧回溯;
* match匹配: 處理返回值`Result`,**匹配**出不同錯(cuò)誤的原因;
* ?運(yùn)算符: **傳播錯(cuò)誤** ,將錯(cuò)誤從一種類(lèi)型轉(zhuǎn)換為另一種類(lèi)型,返回給調(diào)用者;

**](alloc::vec::Vec%3CT,A)

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2987

    瀏覽量

    107197
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1657

    瀏覽量

    49948
  • rust語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    3123
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    聊聊Rust與C語(yǔ)言交互的具體步驟

    rust FFI 是rust與其他語(yǔ)言互調(diào)的橋梁,通過(guò)FFI rust 可以有效繼承 C 語(yǔ)言的歷史資產(chǎn)。本期通過(guò)幾個(gè)例子來(lái)聊聊
    發(fā)表于 07-06 11:15 ?2045次閱讀

    Rust語(yǔ)言錯(cuò)誤處理的機(jī)制

    可能的錯(cuò)誤,實(shí)際運(yùn)行仍然可能出現(xiàn)各種各樣的錯(cuò)誤,比如文件不存在、網(wǎng)絡(luò)連接失敗等等。對(duì)于這些不可預(yù)測(cè)的錯(cuò)誤,我們必須使用錯(cuò)誤處理機(jī)制來(lái)進(jìn)行
    的頭像 發(fā)表于 09-19 14:54 ?1822次閱讀

    基于Rust語(yǔ)言Hash特征的基礎(chǔ)用法和進(jìn)階用法

    Rust語(yǔ)言是一種系統(tǒng)級(jí)編程語(yǔ)言,具有高性能、安全、并發(fā)等特點(diǎn),是近年來(lái)備受關(guān)注的新興編程語(yǔ)言。在Rust
    的頭像 發(fā)表于 09-19 16:02 ?1762次閱讀

    Rust語(yǔ)言如何與 InfluxDB 集成

    的數(shù)據(jù)處理和存儲(chǔ)能力。 本教程將介紹 Rust 語(yǔ)言如何與 InfluxDB 集成,包括基礎(chǔ)用法和進(jìn)階用法和完整的示例代碼。 基礎(chǔ)用法 安裝 InfluxDB Rust 客戶(hù)端 首先,
    的頭像 發(fā)表于 09-30 16:45 ?1428次閱讀

    基于Rust語(yǔ)言中的生命周期

    Rust是一門(mén)系統(tǒng)級(jí)編程語(yǔ)言具備高效、安和并發(fā)等特,而生命周期是這門(mén)語(yǔ)言中比較重要的概念之一。在這篇教程,我們會(huì)了解什么是命周期、為什么需要生命周期、如何使用生命周期,同時(shí)我們依然會(huì)
    的頭像 發(fā)表于 09-19 17:03 ?1115次閱讀

    Rust 語(yǔ)言中的 RwLock內(nèi)部實(shí)現(xiàn)原理

    Rust是一種系統(tǒng)級(jí)編程語(yǔ)言,它帶有嚴(yán)格的內(nèi)存管理、并發(fā)和安全性規(guī)則,因此很受廣大程序員的青睞。RwLock(讀寫(xiě)鎖)是 Rust 中常用的線程同步機(jī)制之一,本文將詳細(xì)介紹 Rust
    的頭像 發(fā)表于 09-20 11:23 ?1138次閱讀

    只會(huì)用Python?教你在樹(shù)莓派上開(kāi)始使用Rust

    如果您對(duì)編程感興趣,那么您可能聽(tīng)說(shuō)過(guò)Rust。該語(yǔ)言由Mozilla設(shè)計(jì),受到開(kāi)發(fā)人員的廣泛喜愛(ài),并繼續(xù)在奉獻(xiàn)者成長(zhǎng)。Raspberry Pi是小型計(jì)算機(jī)的瑞士軍刀,非常適合學(xué)習(xí)代碼
    發(fā)表于 05-20 08:00

    如何用 rust 語(yǔ)言開(kāi)發(fā) stm32

    本文介紹如何用 rust 語(yǔ)言開(kāi)發(fā) stm32。開(kāi)發(fā)平臺(tái)為 linux(gentoo)。硬件準(zhǔn)備本文使用的芯片為 STM32F103C8T6。該芯片性?xún)r(jià)比較高,價(jià)格低廉,適合入門(mén)學(xué)習(xí)。需要
    發(fā)表于 11-26 06:20

    RUST在嵌入式開(kāi)發(fā)的應(yīng)用是什么

    Rust是一種編程語(yǔ)言,它使用戶(hù)能夠構(gòu)建可靠、高效的軟件,尤其是用于嵌入式開(kāi)發(fā)的軟件。它的特點(diǎn)是:高性能:Rust具有驚人的速度和高內(nèi)存利用率。可靠性:在編譯過(guò)程可以消除內(nèi)存
    發(fā)表于 12-24 08:34

    如何利用C語(yǔ)言去調(diào)用rust靜態(tài)庫(kù)呢

    語(yǔ)言的感覺(jué),要做不少的對(duì)接工作。也用過(guò)Lua,感覺(jué)也差不多。評(píng)估學(xué)習(xí)評(píng)估Rust語(yǔ)言時(shí),感覺(jué)性能和體積應(yīng)該都不會(huì)有太大的問(wèn)題。加上語(yǔ)言本身
    發(fā)表于 06-21 10:27

    Rust代碼中加載靜態(tài)庫(kù)時(shí),出現(xiàn)錯(cuò)誤 ` rust-lld: error: undefined symbol: malloc `怎么解決?

    時(shí),出現(xiàn)錯(cuò)誤 ` [i]rust-lld: error: undefined symbol: malloc `。如何將這些定義包含在我的靜態(tài)庫(kù)
    發(fā)表于 06-09 08:44

    微軟開(kāi)發(fā)基于Rust的新編程語(yǔ)言,將很快開(kāi)源

    使用Rust重寫(xiě)各種產(chǎn)品,因?yàn)樵谶^(guò)去的十年里,微軟70%以上的安全補(bǔ)丁都提供了與內(nèi)存相關(guān)的錯(cuò)誤,而Rust正是解決這個(gè)問(wèn)題的良藥。 而根據(jù)ZDNet的報(bào)導(dǎo),近日在一次演講,談到微軟為
    的頭像 發(fā)表于 12-03 10:36 ?4072次閱讀

    以調(diào)試Rust的方式來(lái)學(xué)習(xí)Rust

    在我上一篇 關(guān)于 Rustup 的文章 ,我向你們展示了如何安裝 Rust 工具鏈。但是,如果不能上手操作一下 Rust 的話下載工具鏈又有什么用?學(xué)習(xí)任何
    的頭像 發(fā)表于 01-03 14:56 ?1133次閱讀

    Rust錯(cuò)誤處理方法

    Rust 沒(méi)有提供類(lèi)似于 Java、C++ 的 Exception 機(jī)制,而是使用 Result 枚舉的方式來(lái)實(shí)現(xiàn)。
    的頭像 發(fā)表于 02-20 09:37 ?1231次閱讀

    rust語(yǔ)言基礎(chǔ)學(xué)習(xí): 智能指針之Cow

    Rust與借用數(shù)據(jù)相關(guān)的三個(gè)trait: Borrow, BorrowMut和ToOwned。理解了這三個(gè)trait之后,再學(xué)習(xí)Rust
    的頭像 發(fā)表于 05-22 16:13 ?3269次閱讀
    主站蜘蛛池模板: 日本黄色大片免费观看 | 免费黄视频网站 | 美女好紧好大好爽12p | 亚洲综合成人网在线观看 | 日本黄视频在线观看 | 朋友夫妇和交换性bd高清 | 色 ed2k| 特级黄毛片 | 五月天婷婷丁香中文在线观看 | 欧美在线一级视频 | 福利在线看 | 日本加勒比视频在线观看 | 性free中国美女hd | 亚欧一区 | 六月综合网 | 国产大片免费观看资源 | 222www免费观看 | 国产精品久久久久久久久 | 欧美三级在线视频 | 久久这里精品青草免费 | 亚洲欧美日韩色图 | 在线天堂中文有限公司 | 4虎影视国产在线观看精品 4虎影院永久地址www | 最黄色的视频 | 精品国产免费久久久久久婷婷 | 岛国毛片一级一级特级毛片 | 午夜网站在线 | 免费在线观看一级毛片 | 一级毛片在线播放 | 亚洲人与牲动交xxxxbbbb | 亚洲人成网站色7777 | 手机看片1024在线观看 | 久久精品国产6699国产精 | 亚洲无线码一区在线观看 | 成人做视频免费 | 久久网免费视频 | 亚洲成a人片在线观看尤物 亚洲成a人片在线观看中 | 高清成人| 91午夜在线观看 | 免费看黄资源大全高清 | 免费视频不卡一区二区三区 |