Rust में त्रुटि प्रबंधन: unwrap से उन्नत तकनीकों तक

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Rust में त्रुटि प्रबंधन: unwrap से उन्नत तकनीकों तक



अपवादों वाली भाषाओं (Java, Python, C++) के विपरीत, Rust try/catch तंत्र का उपयोग नहीं करता है। इसके बजाय, भाषा त्रुटियों को संभालने के लिए एक शक्तिशाली और सुरक्षित प्रकार प्रणाली प्रदान करती है। शुरुआती डेवलपर्स अक्सर unwrap() का दुरुपयोग करते हैं, जिससे एप्लिकेशन पैनिक हो जाता है। इस लेख में, हम Rust में त्रुटियों के साथ काम करने की उन्नत तकनीकों पर चर्चा करेंगे: स्वयं के त्रुटि प्रकार बनाने से लेकर thiserror और anyhow क्रेट्स के उपयोग तक, साथ ही try/catch व्यवहार का अनुकरण कैसे करें।



1. Rust ने try/catch को क्यों छोड़ा?



अपवादों वाली भाषाओं में, निष्पादन प्रवाह किसी भी क्षण बाधित हो सकता है। यह कोड विश्लेषण को जटिल बनाता है और संसाधन रिसाव का कारण बन सकता है। Rust दो मुख्य दृष्टिकोण प्रदान करता है:



  • पुनर्प्राप्त करने योग्य त्रुटियाँ — प्रकार Result<T, E> (सफलता Ok(T) या त्रुटि Err(E))।
  • अपूरणीय त्रुटियाँ — मैक्रो panic!, जो प्रोग्राम को रोक देता है।


ऑपरेटर ? Rust में try के समतुल्य है। यह Ok से मान निकालता है या फ़ंक्शन से तुरंत Err लौटाता है।



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

fn read_username(path: &str) -> Result<String, std::io::Error> { let mut file = File::open(path)?; // यदि त्रुटि है — इसे लौटाएँ let mut username = String::new(); file.read_to_string(&mut username)?; // फिर से "try" Ok(username.trim().to_string())}


2. स्वयं के त्रुटि प्रकार बनाना



जटिल परियोजनाओं के लिए, केवल std::io::Error पर्याप्त नहीं है। सबसे अच्छा अभ्यास एनम (enum) का उपयोग करके अपना स्वयं का त्रुटि प्रकार परिभाषित करना है। यह विभिन्न प्रकार की त्रुटियों को समूहित करने और संदर्भ जोड़ने की अनुमति देता है।



use std::fmt;

#[derive(Debug)]enum MyAppError { IoError(std::io::Error), ParseError(String), NetworkError { url: String, status: u16 },}

impl fmt::Display for MyAppError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MyAppError::IoError(e) => write!(f, "IO त्रुटि: {}", e), MyAppError::ParseError(s) => write!(f, "पार्स त्रुटि: {}", s), MyAppError::NetworkError { url, status } => { write!(f, "{} के लिए नेटवर्क त्रुटि: स्थिति {}", url, status) } } }}

impl std::error::Error for MyAppError {} // Error ट्रेट को लागू करें


अब ? का उपयोग स्वचालित रूपांतरण के लिए किया जा सकता है, यदि From ट्रेट लागू किया जाए:



impl From<std::io::Error> for MyAppError {    fn from(err: std::io::Error) -> MyAppError {        MyAppError::IoError(err)    }}

fn process_file(path: &str) -> Result<(), MyAppError> { let content = std::fs::read_to_string(path)?; // स्वचालित रूप से रूपांतरित होता है if content.is_empty() { return Err(MyAppError::ParseError("खाली फ़ाइल".into())); } Ok(())}


3. उन्नत क्रेट्स: thiserror और anyhow



सभी Display और From कार्यान्वयन मैन्युअल रूप से लिखना थकाऊ है। इसके लिए दो लोकप्रिय क्रेट्स मौजूद हैं:



thiserror — लाइब्रेरीज़ के लिए

thiserror क्रेट derive-मैक्रो के माध्यम से std::error::Error का कार्यान्वयन उत्पन्न करता है। लाइब्रेरीज़ के लिए आदर्श है जहाँ त्रुटियों का सटीक विवरण आवश्यक है।



use thiserror::Error;

#[derive(Error, Debug)]pub enum DataError { #[error("IO त्रुटि: {0}")] Io(#[from] std::io::Error), #[error("अमान्य UTF-8: {0}")] Utf8(#[from] std::str::Utf8Error), #[error("कस्टम विफलता: {details}")] Custom { details: String },}

// अब लिख सकते हैं:fn parse_data(bytes: &[u8]) -> Result<String, Da

ब्लॉग

पुस्तक अनुशंसाएँ