偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Rust 錯(cuò)誤處理的五種方式及學(xué)習(xí)特質(zhì)如何支持繼承

開發(fā) 前端
在Rust中,大約有20種處理錯(cuò)誤的模式,而我們這里只看到了其中的5種。練習(xí)多種錯(cuò)誤模式將有助于更容易地識(shí)別這些模式。

在編寫代碼時(shí),學(xué)習(xí)如何處理錯(cuò)誤是非常重要的。錯(cuò)誤通常是由于用戶對(duì)程序目的的誤解而產(chǎn)生的。錯(cuò)誤不僅可以作為用戶的教學(xué)工具,還能提高代碼的效率。與我們用于控制流程的邏輯條件不同,錯(cuò)誤是由于某種期望未被滿足或某個(gè)選項(xiàng)不可用而產(chǎn)生的。Rust提供了五種不同的方法來直接解決這些“期望”和“不可用”的問題。

錯(cuò)誤最終服務(wù)于用戶和開發(fā)者

當(dāng)用戶收到晦澀難懂的錯(cuò)誤反饋時(shí),他們會(huì)感到沮喪。而開發(fā)者則希望看到導(dǎo)致崩潰的一系列事件或函數(shù)調(diào)用。這導(dǎo)致我們將錯(cuò)誤視為字符串和結(jié)構(gòu)化類型。

觀察Python如何處理錯(cuò)誤

在學(xué)習(xí)Rust的錯(cuò)誤處理時(shí),通過比較和對(duì)比Python的錯(cuò)誤處理方式是非常有效的。這樣可以更容易地發(fā)現(xiàn)模式。

Python與Rust的比較與對(duì)比

無錯(cuò)誤處理:主函數(shù)引發(fā)異常并失敗
result = 10 / 0
print(result)

輸出:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
Try Except:捕獲邊界情況
try:
    result = 10 / 0  # This will raise ZeroDivisionError
except ZeroDivisionError:
    print("Cannot divide by zero!")
except TypeError:
    print("Type error occurred!")
Try Except Finally:確保異常期間的正確清理
try:
    file = open("example.txt", "r")
except FileNotFoundError:
    print("File not found.")
finally:
    print("Closing file (if open).")
    if 'file' in locals() and not file.closed:
        file.close()
Raising Exception:崩潰代碼/由調(diào)用函數(shù)處理
age = -1
if age < 0:
    raise ValueError("Age cannot be negative!")
創(chuàng)建自定義錯(cuò)誤:為開發(fā)者提供結(jié)構(gòu)化錯(cuò)誤
class ApplicationError(Exception):
    """Base class for all application errors."""
    pass

class DatabaseError(ApplicationError):
    """Exception raised for database-related errors."""
    pass

class APIError(ApplicationError):
    """Exception raised for API-related errors."""
    pass

# Usage
try:
    raise DatabaseError("Unable to connect to the database.")
except DatabaseError as e:
    print(f"Database error: {e}")
except ApplicationError:
    print("General application error.")

通過這些處理,程序可以繼續(xù)運(yùn)行,直到用戶關(guān)閉應(yīng)用程序。在此過程中,我們可以看到用戶請(qǐng)求是如何被服務(wù)的,以及支持設(shè)備和應(yīng)用程序在做什么。

觀察Rust如何處理錯(cuò)誤

現(xiàn)在輪到Rust了。錯(cuò)誤處理中的術(shù)語如Panic、Unwrap、Expect,以及“?”,每一個(gè)都讓我們采取行動(dòng),編寫更好的代碼。在Rust中讓代碼Panic被認(rèn)為是不好的做法。構(gòu)建應(yīng)用程序或庫時(shí),定義良好的錯(cuò)誤處理是關(guān)鍵。

無錯(cuò)誤處理:Panic!

fn main() {
    let x = 50;
    let y = 0;
    let rs = x / y;
    println!("{}", rs)
}

輸出:

thread 'main' panicked at 'attempt to divide by zero', src/main.rs:11:14

Catch Unwind:捕獲邊界情況

fn main() {
    let x = 50;
    let y = 10;
    let cuw = std::panic::catch_unwind(|| x / y);
    match cuw {
        Ok(val) => println!("Got the {val}"),
        Err(e) => println!("Error: {:?}", e),
    }
}

Rust中的存在檢測(cè):match、Results和Options

Rust是一種強(qiáng)類型和內(nèi)存安全的語言,這導(dǎo)致了Enum的獨(dú)特子數(shù)據(jù)類型Options和Results。兩者都處理我們感興趣的事物的“存在”和“不存在”。match關(guān)鍵字用于檢查返回類型是否為Enum的任何變體。在Option的情況下,它是None或一個(gè)可以處理和使用的“已知Rust數(shù)據(jù)類型”。在Result的情況下,它是Error或我們追求的“值”。

在函數(shù)中引發(fā)錯(cuò)誤:傳播錯(cuò)誤

use std::error::Error;

fn div_by_zero(a: i32, b: i32) -> Result<i32, Box<dyn Error>> {
    if b == 0 {
        return Err("Divide by 0, leads to infinity....".into());
    }
    Ok(a / b)
}

fn main() {
    println!("Doing what catch unwind does, manually");
    let err_rs = div_by_zero(57, 0);
    let val_rs = div_by_zero(50, 5);
    match err_rs {
        Ok(val) => println!("Got {val}"),
        Err(e) => eprintln!("Got {:?}", e),
    }
    match val_rs {
        Ok(val) => println!("Got {val}"),
        Err(e) => eprintln!("Got {:?}", e),
    }
}

創(chuàng)建自定義錯(cuò)誤:為開發(fā)者提供結(jié)構(gòu)化錯(cuò)誤輸出

use std::error::Error;
#[derive(Debug)]
struct ZeroDivideError {
    details: String,
}

impl ZeroDivideError {
    fn new(msg: &str) -> ZeroDivideError {
        ZeroDivideError {
            details: msg.to_string(),
        }
    }
}

use std::fmt::Display;
impl Error for ZeroDivideError {}
impl Display for ZeroDivideError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Zero divide: {}", self.details)
    }
}

fn div_by_zero_error(a: i32, b: i32) -> Result<i32, ZeroDivideError> {
    if b == 0 {
        return Err(ZeroDivideError::new("Structured output"));
    }
    Ok(a / b)
}

fn main() {
    println!("Creating Custom Errors");
    let err_rs = div_by_zero_error(57, 0);
    let val_rs = div_by_zero_error(50, 5);
    match err_rs {
        Ok(val) => println!("Got {val}"),
        Err(e) => eprintln!("Got {:?}", e),
    }
    match val_rs {
        Ok(val) => println!("Got {val}"),
        Err(e) => eprintln!("Got {:?}", e),
    }
}

輸出:

Creating Custom Errors
Got ZeroDivideError { details: "Structured output" }
Got 10

錯(cuò)誤類型依賴于實(shí)現(xiàn)的Traits

結(jié)構(gòu)體ZeroDivideError是Rust中的一個(gè)標(biāo)準(zhǔn)結(jié)構(gòu)體。在Rust中,結(jié)構(gòu)體相當(dāng)于Python中的類。通過impl Error for ZeroDivideError,我們將ZeroDivideError變成了一個(gè)“錯(cuò)誤類型結(jié)構(gòu)體”。我們還需要為ZeroDivideError實(shí)現(xiàn)std::fmt::Display,以便將錯(cuò)誤顯示給用戶或開發(fā)者。

動(dòng)態(tài)處理不同錯(cuò)誤:使用Box

Box<dyn Error>在函數(shù)可能返回不同類型的錯(cuò)誤時(shí)非常有用,可以統(tǒng)一處理這些錯(cuò)誤。動(dòng)態(tài)分派(dyn)通過允許運(yùn)行時(shí)多態(tài)性實(shí)現(xiàn)這一點(diǎn)。

use std::error::Error;
#[derive(Debug)]
struct ZeroDivideError {
    details: String,
}

impl ZeroDivideError {
    fn new(msg: &str) -> ZeroDivideError {
        ZeroDivideError {
            details: msg.to_string(),
        }
    }
}

use std::fmt::Display;
impl Error for ZeroDivideError {}
impl Display for ZeroDivideError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Zero divide: {}", self.details)
    }
}

// Combining different error types using `Box<dyn Error>`
pub fn parse_and_double(input: &str) -> Result<i32, Box<dyn Error>> {
    let number = input.parse::<i32>()?;
    Ok(number * 2)
}

pub fn parse_and_dbl(input: &str) -> Result<i32, ZeroDivideError> {
    let number = input.parse::<i32>();
    match number {
        Err(_) => {
            return Err(ZeroDivideError::new(
                "Negative number due to number parsing",
            ))
        }
        Ok(number) => return Ok(number * 2),
    }
}

fn main() {
    println!("Creating Custom Errors");
    let parseme = parse_and_double("56,");
    let prsme = parse_and_dbl("56,");
    match parseme {
        Ok(val) => println!("Got {val}"),
        Err(e) => eprintln!("Got {:?}", e.to_string()),
    }
    match prsme {
        Ok(val) => println!("Got {val}"),
        Err(e) => eprintln!("Got {:?}", e.to_string()),
    }
}

輸出:

Creating Custom Errors
Got "invalid digit found in string"
Got "Zero divide: Negative number due to number parsing"

這并不是Rust中錯(cuò)誤處理的全部。在Rust中,大約有20種處理錯(cuò)誤的模式,而我們這里只看到了其中的5種。練習(xí)多種錯(cuò)誤模式將有助于更容易地識(shí)別這些模式。

責(zé)任編輯:武曉燕 來源: Rust開發(fā)筆記
相關(guān)推薦

2024-03-05 18:15:28

AsyncAwait前端

2025-02-10 09:49:00

2023-10-08 20:31:18

React

2023-03-10 08:48:29

2023-02-22 16:33:04

前端JavaScript

2015-08-19 14:11:56

SQL Server錯(cuò)誤處理

2025-03-18 09:20:00

Go語言Golang

2023-10-26 12:05:14

Golang開發(fā)

2021-04-14 07:08:14

Nodejs錯(cuò)誤處理

2024-03-27 08:18:02

Spring映射HTML

2014-11-17 10:05:12

Go語言

2014-01-13 10:36:53

C++錯(cuò)誤

2021-04-29 09:02:44

語言Go 處理

2022-02-23 12:35:12

LibreOffic無障礙輔助套件

2025-01-13 00:00:00

MapStruct繼承關(guān)系Java

2022-12-30 11:05:40

Rust代碼

2023-12-26 22:05:53

并發(fā)代碼goroutines

2025-05-16 10:53:43

開發(fā)異步編程JavaScrip

2022-11-16 08:41:43

2013-01-09 15:46:02

Android百度定位SDKGPS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)