改進rust代碼的35種具體方法-類型(十八)-不要驚慌

上一篇文章


它看起來非常復雜,這就是為什么它貼合的塑料蓋上用大號友好字母印上“不要恐慌”的原因之一。——道格拉斯·亞當斯

此項目的標題將更準確地描述為更喜歡返回Result而不是使用panic!(但不要驚慌更吸引人)。

Rust的panic機制主要是為程序中不可恢復的錯誤而設計的,默認情況下它會終止發出panic的線程。然而,這個默認值還有其他替代方案。

特別是,來自具有異常系統(如Java或C++)的語言的Rust新手有時會撲向std::panic::catch_unwind作為模擬異常的一種方式,因為它似乎提供了一種在呼叫堆棧更遠的點捕獲恐慌的機制。

fn divide(a: i64, b: i64) -> i64 {if b == 0 {panic!("Cowardly refusing to divide by zero!");}a / b
}

嘗試用無效輸入調用此內容,按預期失敗:

// Attempt to discover what 0/0 is...
let result = divide(0, 0);

thread 'main' panicked at 'Cowardly refusing to divide by zero!', main.rs:11:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
?

使用catch_unwind捕捉恐慌的包裝器:

fn divide_recover(a: i64, b: i64, default: i64) -> i64 {let result = std::panic::catch_unwind(|| divide(a, b));match result {Ok(x) => x,Err(_) => default,}
}

似乎工作并模擬catch

let result = divide_recover(0, 0, 42);
println!("result = {result}");
result = 42

然而,外表可能是欺騙性的。這種方法的第一個問題是,恐慌并不總是解除;有一個編譯器選項(也可以通過Cargo.toml配置文件設置訪問),可以轉移恐慌行為,以便立即中止該過程:

thread 'main' panicked at 'Cowardly refusing to divide by zero!', main.rs:11:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
/bin/sh: line 1: 29100 Abort trap: 6 ?cargo run --release

這使得任何模擬異常的嘗試完全受制于更廣泛的項目設置。同樣,一些目標平臺(例如WebAssembly)總是在恐慌時中止,無論任何編譯器或項目設置如何。

恐慌處理暴露的一個更微妙的問題是異常安全:如果恐慌發生在數據結構操作的中途,它會消除數據結構處于自洽狀態的任何保證。眾所周知,自20世紀90年代以來,在存在異常的情況下保留內部不變量是非常困難的;1這是谷歌(著名的)禁止在其C++代碼中使用異常的主要原因之一。

最后,恐慌傳播也與FFI(外部函數接口)邊界的相互作用很差;使用catch_unwind防止Rust代碼中的恐慌跨越FFI邊界傳播到非Rust調用代碼

那么,除了恐慌,還有什么辦法呢?處理錯誤條件?對于庫代碼,最好的替代方法是通過返回帶有適當錯誤類型(Item 4)的Result,使錯誤成為其他人的問題。這允許庫用戶自己決定下一步要做什么——這可能涉及將問題傳遞給行中的下一個調用者,通過?操作符。

責任總有止點,一個有用的經驗法則是,恐慌是可以的!(或者unwrap(), expect()等),如果你控制了main;在這一點上,沒有進一步的調用者可以將責任傳遞給。

又一個明智的恐慌!即使在庫代碼中,在很少遇到錯誤的情況下也是如此,并且您不希望用戶不得不使用.unwrap()調用來丟棄他們的代碼。

如果錯誤情況只是因為(例如)內部數據損壞,而不是由于無效的輸入,那么就會引發panic!是合法的。

允許由無效輸入觸發的恐慌,但此類無效輸入不同尋常,這甚至偶爾也是有用的。當相關切入點成對出現時,這效果最佳:

對于前者,Rust的API指南表明panic!應在內聯文檔的特定部分中記錄。

標準庫中的String::from_utf8_unchecked和String::from_utf8入口點是后者的一個例子(盡管在這種情況下,恐慌實際上被推遲到使用由無效輸入構造的aString)。

假設您試圖遵守本項目中的建議,有幾件事需要記住。首先,恐慌可以以不同的形式出現;避免panic!還涉及避免以下內容:

更難發現的是以下東西:

  • slice[index]當指數不在范圍之內時
  • x / yy為零時

關于避免恐慌的第二個觀察是,一個涉及人類持續警惕的計劃從來都不是一個好主意。

然而,對機器的持續警惕是另一回事:在您的持續集成系統中添加檢查,以發現新的、可能恐慌的代碼要可靠得多。一個簡單的版本可能是最常見的恐慌進入點的簡單grep(如前所示);更徹底的檢查可能涉及來自Rust生態系統的額外工具,例如設置一個構建變體來拉入no_panic板條箱。


1 Tom Cargill1994年在C++報告中的文章探討了C++模板代碼的異常安全有多困難,Herb Sutter的本周大師#8專欄也是如此。


下一篇文章-避免使用反射icon-default.png?t=N7T8https://blog.csdn.net/qq_34841911/article/details/139180459

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/web/14613.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/14613.shtml
英文地址,請注明出處:http://en.pswp.cn/web/14613.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

算法入門----小話算法(1)

下面就首先從一些數學問題入手。 Q1&#xff1a; 如何證明時間復雜度O(logN) < O(N) < O(NlogN) < O(N2) < O(2N) < O(N!) < O(NN)? A&#xff1a; 如果一個以整數為參數的不等式不能很容易看出不等的關系&#xff0c;那么最好用圖示或者數學歸納法。 很顯…

Python3 筆記:sort() 和 sorted() 的區別

1、sort() 可以對列表中的元素進行排序&#xff0c;會改變原列表&#xff0c;之前的順序不復存在。 list.sort&#xff08;key&#xff0c; reverse None&#xff09; key&#xff1a;默認值是None&#xff0c;可指定項目進行排序&#xff0c;此參數可省略。 reverse&#…

rmxprt轉換的3D模型只有一半?---模大獅模型網

在3D建模和渲染的工作流程中&#xff0c;我們經常需要用到各種轉換工具來兼容不同平臺或軟件之間的模型格式。rmxprt(或其他類似的模型轉換工具)就是其中的一種&#xff0c;它能夠將模型從一種格式轉換為另一種格式。然而&#xff0c;有時在轉換過程中可能會遇到一些問題&#…

微服務雪崩問題、Sentinel(請求限流、線程隔離、服務熔斷)、Seata分布式事務

文章目錄 前言一、微服務保護二、Sentinel2.1 微服務整合2.2 簇點鏈路2.3 請求限流2.4 線程隔離2.5 服務熔斷 三、分布式事務3.1 Seata3.1.1 Seata架構3.1.2 部署TC服務3.1.3 微服務集成Seata 3.2 XA模式3.3 AT模式 前言 微服務之間為什么會雪崩&#xff1f;怎么解決雪崩問題&…

MySQL存儲過程淺析

存儲過程 定義&#xff1a; 存儲過程是一組為了完成特定功能的SQL語句&#xff0c;是由一些SQL語句組成的代碼塊&#xff0c;這些代碼塊像方法一樣實現一些功能&#xff08;對單表或多表的增刪改查&#xff09;&#xff0c;然后給代碼塊起一個名字&#xff0c;用到的時候再調用…

Oracle體系結構初探:數據庫啟動與停止

往期內容 參數管理 控制文件添加 啟動 在啟動Oracle數據庫時&#xff0c;我們一般會使用如下命令&#xff1a; startup 雖然命令只有一個&#xff0c;但其中卻是經歷了3個階段&#xff0c;從下面執行 startup 命令返回也可以看出來。 總結為3個階段&#xff1a; nomount&…

ubuntu下python導入.so庫

ubuntu下python導入.so庫 文章目錄 ubuntu下python導入.so庫1. 什么是.so文件&#xff1f;2. 使用python腳本編譯.so庫文件Reference 最近遇到了python導入c編譯的 .so庫的問題&#xff0c;發覺挺有意思&#xff0c;于是寫下這篇blog以作記錄。 1. 什么是.so文件&#xff1f; …

【簡單介紹下深度神經網絡】

&#x1f3a5;博主&#xff1a;程序員不想YY啊 &#x1f4ab;CSDN優質創作者&#xff0c;CSDN實力新星&#xff0c;CSDN博客專家 &#x1f917;點贊&#x1f388;收藏?再看&#x1f4ab;養成習慣 ?希望本文對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出…

句柄降權繞過CallBacks檢查

看到前輩們相關的文章&#xff0c;不太明白什么是句柄降權&#xff0c;于是專門去學習一下&#xff0c;過程有一點波折。 句柄降權 什么是句柄 當一個進程利用名稱來創建或打開一個對象時&#xff0c;將獲得一個句柄&#xff0c;該句柄指向所創建或打開的對象。以后&#xf…

什么是DNS緩存投毒攻擊,有什么防護措施

隨著企業組織數字化步伐的加快&#xff0c;域名系統&#xff08;DNS&#xff09;作為互聯網基礎設施的關鍵組成部分&#xff0c;其安全性愈發受到重視。然而&#xff0c;近年來頻繁發生的針對DNS的攻擊事件&#xff0c;已經成為企業組織數字化發展中的一個嚴重問題。而在目前各…

go string 實現

在go中string是不可變的&#xff0c;這意味著對string發生改變的操作實際上都是通過分配新的string去實現的 在string內存分配上&#xff0c;對于小對象分配到棧&#xff0c;大對象分配到堆中 string在go中的結構其實很簡單&#xff0c;就是一個指向實際數據的指針以及字符串…

用于與 HTTP 服務器通信的函數

用于與 HTTP 服務器通信的函數 Plant Simulation 提供了許多使用 HTTP 協議與 HTTP 服務器通信的函數。可使用這些函數來發送 HTTP 請求、發送數據和從 HTTP 響應中接收數據&#xff0c;以及在 HTTP 服務器上創建和刪除資源&#xff1a; httpGetRequest 發送 GET 請求。請求…

在 Visual Studio 2022 (VS2022) 中刪除 Git 分支的步驟如下

git branch -r PS \MauiApp1> git push origin --delete “20240523備份” git push origin --delete “20240523備份”

PCL 常用小知識

文章目錄 一、時間計算二、實現類似`pcl::PointCloud::Ptr`和`pcl::PointCloud`的兩個類相互轉換三、查找點云的x,y,z的極值四、知道需要保存點的索引,從原點云中拷貝點到新點云五、從點云里刪除和添加點六、對點云進行全局或局部變換七、鏈接兩個點云字段(兩點云大小必須相…

若依 ruoyi-vue 用戶賬號前后端參數校驗密碼 手機號 郵箱

前端 <el-dialog :title"title" :visible.sync"open" width"800px" append-to-body><el-form ref"form" :model"form" :rules"rules" label-width"120px"><el-row><el-col :span…

Vue3骨架屏(Skeleton)

效果如下圖&#xff1a;在線預覽 APIs 參數說明類型默認值必傳animated是否展示動畫效果booleantruefalsebutton是否使用按鈕占位圖boolean | SkeletonButtonPropsfalsefalseavatar是否顯示頭像占位圖boolean | SkeletonAvatarPropsfalsefalseinput是否使用輸入框占位圖boolea…

SOLIDWORKS二次開發服務商 慧德敏學

SOLIDWORKS是一套三維設計軟件, 采用特征建模、變量化驅動可方便地實現三維建模、裝配和生成工程圖。SOLIDWORKS軟件本身所具有的交互方式, 可以使用戶對已生成模型的尺寸、幾何輪廓和相互約束關系隨時進行修改, 而不需要編程。但要實現設計意義上的變量化繪圖和系列化設計, 需…

java-查詢字符串當中是否包含中文

文章目錄 前言java-查詢字符串當中是否包含中文 前言 如果您覺得有用的話&#xff0c;記得給博主點個贊&#xff0c;評論&#xff0c;收藏一鍵三連啊&#xff0c;寫作不易啊^ _ ^。 ??而且聽說點贊的人每天的運氣都不會太差&#xff0c;實在白嫖的話&#xff0c;那歡迎常來啊…

軟考系統架構師一些知識點記錄-1

個人隨筆 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 引言 準備去參加軟考的考試&#xff0c;但對一些概念掌握的還不夠&#xff0c;借此機會&#xff0c;整理記錄一二&#xff0c;便于自己理解掌握。 知識范圍 感覺不夠清晰的部分主要是第三篇和第四篇的部分。…

國際頂會認可!KaiwuDB 論文入選 ICDE 2024

導 讀 近日&#xff0c;KaiwuDB 與中國人民大學合作的論文 FOSS: A Self-Learned Doctor for Query Optimizer 被數據庫領域頂會The 40th IEEE International Conference on Data Engineering (ICDE 2024) 錄用啦! 論文中提出了具備自學習、自診斷能力的查詢優化器 FOSS&…