rust學習筆記17-異常處理

今天聊聊rust中異常錯誤處理

1. 基礎類型:Result 和 Option,之前判斷空指針就用到過

Option<T>
  • 用途:表示值可能存在(Some(T))或不存在(None),適用于無需錯誤信息的場景。

    fn print_list(head: Option<&Box<ListNode>>) {match head {Some(node) => {let mut current = Some(node); // 初始化當前節點指針while let Some(node) = current {print!("{} -> ", node.val);current = node.next.as_ref(); // 使用 as_ref() 獲取對 next 的引用}println!("None");}None => {println!("鏈表為空");}}
    }

Result<T, E>
  • 用途:表示操作可能成功(Ok(T))或失敗(Err(E)),E?為錯誤類型。

    fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {if denominator == 0.0 {Err(String::from("Denominator cannot be zero!"))} else {Ok(numerator / denominator)}
    }

2.快捷方法:unwrap 和 expect?

unwrap():成功返回值,失敗則 panic。

expect(msg):類似 unwrap,但可附加錯誤信息。

let content = read_file("file.txt").unwrap(); // 危險:可能崩潰let content = read_file("file.txt").expect("讀取文件失敗");

3.錯誤傳播:? 運算符
????????簡化錯誤傳播:自動將錯誤返回給調用者,需函數返回 Result。

fn process_file() -> Result<(), std::io::Error> {let content = read_file("file.txt")?; // 錯誤時直接返回println!("Content: {}", content);Ok(())
}

4.自定義錯誤,一般接口校驗用的多

寫一個校驗錯誤有如下四個,id為空,name重名,id查詢為空,name限制30字符超長錯誤

use std::fmt;
//原生寫法
// 定義校驗錯誤枚舉
#[derive(Debug, PartialEq)]
pub enum ValidationError {IdEmpty,NameDuplicate(String),  // 攜帶重復的名稱IdNotFound(String),     // 攜帶未找到的IDNameTooLong(usize),     // 攜帶實際長度
}// 實現錯誤描述
impl fmt::Display for ValidationError {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {match self {ValidationError::IdEmpty => write!(f, "ID不能為空"),ValidationError::NameDuplicate(name) => write!(f, "名稱 '{}' 已存在", name),ValidationError::IdNotFound(id) => write!(f, "ID '{}' 不存在", id),ValidationError::NameTooLong(len) => write!(f, "名稱長度不能超過30字符(當前長度:{})", len),}}
}// 實現標準錯誤Trait
impl std::error::Error for ValidationError {}

使用 thiserror 簡化(推薦)

[dependencies]
thiserror = "1.0"

use thiserror::Error;#[derive(Error, Debug, PartialEq)]
pub enum ValidationError {#[error("ID不能為空")]IdEmpty,#[error("名稱 '{0}' 已存在")]NameDuplicate(String),#[error("ID '{0}' 不存在")]IdNotFound(String),#[error("名稱長度不能超過30字符(當前長度:{0})")]NameTooLong(usize),
}// 校驗用戶輸入
pub fn validate_user_input(id: &str, name: &str) -> Result<(), ValidationError> {// 檢查ID是否為空if id.trim().is_empty() {return Err(ValidationError::IdEmpty);}// 檢查名稱長度if name.len() > 30 {return Err(ValidationError::NameTooLong(name.len()));}Ok(())
}// 模擬檢查名稱是否重復
pub fn check_name_unique(name: &str) -> Result<(), ValidationError> {let existing_names = vec!["Alice", "Bob"];if existing_names.contains(&name) {return Err(ValidationError::NameDuplicate(name.to_string()));}Ok(())
}// 模擬根據ID查詢數據是否存在
pub fn find_by_id(id: &str) -> Result<(), ValidationError> {let valid_ids = vec!["1001", "1002"];if !valid_ids.contains(&id) {return Err(ValidationError::IdNotFound(id.to_string()));}Ok(())
}fn main() {let existing_names = vec![String::from("Alice"), String::from("Bob")];// 測試不同的錯誤場景match validate_user_input("", "Charlie") {Ok(_) => println!("校驗成功."),Err(e) => println!("校驗失敗: {}", e),}match check_name_unique( "Alice") {Ok(_) => println!("校驗成功."),Err(e) => println!("校驗失敗: {}", e),}match find_by_id("789") {Ok(_) => println!("校驗成功."),Err(e) => println!("校驗失敗: {}", e),}match validate_user_input("123", &"A".repeat(31)) {Ok(_) => println!("校驗成功."),Err(e) => println!("校驗失敗: {}", e),}
}

總結,rust沒有try/catch這樣的異常處理機制,而是通過Result 和 Option這樣枚舉處理,unwrap 和 expect在開發調試過程中用比較多,自定義錯誤,校驗類函數用的多。

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

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

相關文章

Python:單繼承方法的重寫

繼承&#xff1a;讓類和類之間轉變為父子關系&#xff0c;子類默認繼承父類的屬性和方法 單繼承&#xff1a; class Person:def eat(self):print("eat")def sing(self):print("sing") class Girl(Person):pass#占位符&#xff0c;代碼里面類下面不寫任何東…

記錄一下aes加密與解密

該文章只做拓展后續會更新&#xff1b;如有出錯請指出 首先需要先引入相關依賴 crypto-js 然后直接開始存儲 export function aesEncrypt(message: string, key: string) {return aes.encrypt(message, key).toString(); } 之后是解密方式 function decrypt(content: any, key…

[免費]直接整篇翻譯pdf工具-支持多種語言

<閑來沒事寫篇博客填補中文知識庫漏洞> 如題&#xff0c;[免費][本地]工具基于開源倉庫&#xff1a; 工具 是python&#xff01;太好了&#xff0c;所以各個平臺都可以&#xff0c;我這里基于windows. 1. 先把github代碼下載下來&#xff1a; git clone https://githu…

UI設計中的用戶反饋機制:提升交互體驗的關鍵

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在數字化產品泛濫的今天&#xff0c;用戶與界面的每一次交互都在無形中塑造著他們對產品的認知。一個…

Hessian 矩陣是什么

Hessian 矩陣是什么 目錄 Hessian 矩陣是什么Hessian 矩陣的性質及舉例說明**1. 對稱性****2. 正定性決定極值類型****特征值為 2(正),因此原點 ( 0 , 0 ) (0, 0) (0,0) 是極小值點。****3. 牛頓法中的應用****4. 特征值與曲率方向****5. 機器學習中的實際意義**一、定義與…

Nginx 代理訪問一個 Web 界面時缺少內容

1. 資源路徑問題 Web 頁面中的靜態資源&#xff08;如圖片、CSS、JavaScript 文件&#xff09;可能使用了相對路徑或絕對路徑&#xff0c;而這些路徑在代理后無法正確加載。 解決方法&#xff1a; 檢查資源路徑&#xff1a;打開瀏覽器的開發者工具&#xff08;按 F12&#xf…

GPU視頻編解碼:Jetson VPI+multimedia_api視頻編解碼入門(一)

目錄 一.Pipline與工具棧 二.硬件設備概況 三.GPU視頻編解碼框架 四.VPI編譯使用實例 五. jetson_multimedia_api編譯使用實例 一.Pipline與工具棧 二.硬件設備概況 三.GPU視頻編解碼框架 jetson設備目前不支持VPF框架&#xff0c;關于VPF的使用我在下節PC段使用X86進行安…

《深入理解AOP編程:從基礎概念到Spring實現》

AOP編程 AOP(Aspect Oriented Programing) 面向切面編程 Spring動態代理開發 以切面為基本單位的程序開發&#xff0c;通過切脈你間的彼此協同&#xff0c;相互調用&#xff0c;完成程序構建 切面切入點額外功能 OOP(Object Oriented Programing)面向對象編程 java 以對象為基本…

C# 零基礎入門篇(19.DateTime 使用指南)

## 一、概述 DateTime 是 C# 中用于表示日期和時間的結構&#xff0c;位于 System 命名空間中。它提供了豐富的屬性和方法&#xff0c;用于處理日期和時間的創建、格式化、比較和計算。 ## 二、創建 DateTime 對象 ### &#xff08;一&#xff09;使用默認構造函數 DateTime…

Docker 實踐與應用舉例

一、引言 在當今快速發展的信息技術領域&#xff0c;容器化技術已成為推動軟件開發、部署和運維變革的關鍵力量。Docker 作為容器化技術的領軍者&#xff0c;以其高效、便捷、可移植等特性&#xff0c;被廣泛應用于各種場景。它能夠將應用程序及其依賴項打包成一個獨立的容器&…

C++初階——類和對象(一)

C初階——類和對象&#xff08;一&#xff09; 一、面向過程和面向對象 1.面向過程 面向過程的程序設計&#xff08;Procedure-Oriented Programming&#xff09;&#xff0c;簡稱POP&#xff0c;是一種是以程序執行流程為核心的編程范式。它是先分析出解決問題所需要的的步…

Skyeye 云智能制造辦公系統 VUE 版本 v3.15.13 發布

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代碼平臺、移動端采用 UNI-APP。包含 30 多個應用模塊、50 多種電子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、筆記、知識庫、項目、門店、商城、財務、多班次考勤、薪資、招聘、云售后、論壇、公告、問卷、報表…

Obsidian Copilot:打造你的專屬 AI 筆記助手

Obsidian Copilot作為一款非常受歡迎的Obsidian插件&#xff0c;不僅極大地提升了用戶的筆記管理和信息檢索效率&#xff0c;還通過其多樣化的AI功能為用戶帶來了前所未有的便捷體驗。本文將詳細介紹Obsidian Copilot的核心特點、使用方法及個人體驗分享。 核心特點 Obsidian…

每日一題--計算機網絡

一、基礎概念類問題 1. TCP 和 UDP 的區別是什么&#xff1f; 回答示例&#xff1a; TCP&#xff1a;面向連接、可靠傳輸&#xff08;通過三次握手建立連接&#xff0c;丟包重傳&#xff09;、保證數據順序&#xff08;如文件傳輸、網頁訪問&#xff09;。 UDP&#xff1a;無…

使用 Spring 的 FactoryBean 創建和獲取 Bean 對象

在Spring框架中&#xff0c;FactoryBean接口提供了一種強大的機制來創建復雜的bean實例。本文將基于提供的代碼示例&#xff0c;詳細介紹如何通過FactoryBean創建bean對象&#xff0c;并展示如何獲取這些bean實例以及它們所屬的FactoryBean實例。 示例代碼類 定義 MyBean 接口…

制造業數字化轉型,汽車裝備制造企業數字化轉型案例,智能制造數字化傳統制造業數字化制造業數字化轉型案例

《某制造業企業信息化整體解決方案》PPT展示了一個汽車裝備企業的整體信息化解決方案&#xff0c;闡述了該企業的業務特點和現狀&#xff0c;主要包括按訂單生產、多級計劃和產品跟蹤等&#xff0c;分析了信息化建設的主要困難&#xff0c;如信息管理手工化、過程數據追溯困難、…

軟鏈接 使用筆記 linux命令 if判斷

目錄 1>0判斷怎么寫&#xff1a; 1. 使用 [ ] 進行數值比較&#xff1a; 2. 使用 (( )) 進行數學運算&#xff1a; 3. 使用 [[ ]]&#xff08;主要用于字符串比較&#xff0c;不推薦用于數學運算&#xff09;&#xff1a; 軟鏈接 使用筆記 1>0判斷怎么寫&#xff1a…

pycharm-python國際象棋遊戲代碼

嗯&#xff0c;用戶的問題是“pycharm寫關於python國際象棋遊戲代碼”&#xff0c;也就是要用PyCharm來寫一個Python的國際象棋游戲代碼。我需要先整理一下用戶提供的搜索結果&#xff0c;看看有什么相關的信息可以利用。 首先看搜索結果中的各個網頁內容。網頁1主要講的是象棋…

【Film】MovieAgent:自動化電影生成通過多智能體CoT規劃

論文概覽 自動化電影生成根據劇本概要和角色庫創建具有一 致角色、同步字幕和音頻的長篇視頻。它涉及自動化敘 事規劃、場景結構化, 和鏡頭構圖,復制現實世界電影制作的層次推理。 核心貢獻 提出MovieAgent,通過多智能體鏈式思維(CoT)規劃實現自動化電影生成。首次探索并…

數據結構——最短路(BFS,Dijkstra,Floyd)

完整版可以看我的最短路問題模版總結_稠密圖最短路-CSDN博客 考研數據結構只考BFS,Dijkstra和Floyd 下面代碼以Acwing模板題為例 BFS代碼 適用類型&#xff1a; 1.單源最短路徑 2.無權圖 3.不適用于帶權圖和負權回路圖 //Acwing走迷宮bfs #include<bits/stdc.h>usi…