Rust में त्रुटि प्रबंधन: try/catch और उससे आगे — पूर्ण गाइड

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

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

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

Rust में त्रुटि प्रबंधन: सुरक्षा के पक्ष में try/catch का त्याग

\n\n

Python या Java के विपरीत, Rust में क्लासिक try/catch संरचना नहीं है। भाषा के डेवलपर्स ने एक अलग रास्ता अपनाया, त्रुटि प्रबंधन को प्रकार प्रणाली का हिस्सा बनाया। यह कोई सनक नहीं है, बल्कि एक मौलिक निर्णय है जो संकलन चरण में मेमोरी सुरक्षा और प्रोग्राम संचालन की पूर्वानुमेयता की गारंटी देता है। इस लेख में, हम Rust में त्रुटि प्रबंधन के सभी तरीकों को कवर करेंगे: बुनियादी Result और Option से लेकर ? ऑपरेटर और कस्टम त्रुटि प्रकारों के साथ उन्नत तरीकों तक।

\n\n

1. दो मुख्य प्रकार: Result और Option

\n\n

Rust में सभी त्रुटियाँ दो श्रेणियों में विभाजित होती हैं: पुनर्प्राप्त करने योग्य (Result के माध्यम से संभाली जाती हैं) और पुनर्प्राप्त न करने योग्य (panic! की ओर ले जाती हैं)। साथ ही, उन मामलों के लिए Option प्रकार भी है जहाँ मान अनुपस्थित हो सकता है।

\n\n

Result प्रकार

\n\n

Result<T, E> एक एनुम (enum) है जो या तो Ok(T) (डेटा के साथ सफलता) या Err(E) (विवरण के साथ त्रुटि) हो सकता है। यह अपेक्षित त्रुटियों को संभालने का मुख्य उपकरण है: I/O त्रुटियाँ, पार्सिंग त्रुटियाँ, नेटवर्क अनुरोध त्रुटियाँ।

\n\n
use std::fs::File;\nuse std::io::Read;\n\nfn read_file_content(path: &str) -> Result<String, std::io::Error> {\n    let mut file = File::open(path)?;\n    let mut content = String::new();\n    file.read_to_string(&mut content)?;\n    Ok(content)\n}
\n\n

Option प्रकार

\n\n

Option<T> एक और एनुम है जो Some(T) (मान मौजूद है) या None (मान मौजूद नहीं है) मान लेता है। इसका उपयोग तब किया जाता है जब डेटा की अनुपस्थिति एक सामान्य स्थिति हो, त्रुटि नहीं।

\n\n
fn find_user(id: u32) -> Option<String> {\n    let users = vec!["Alice".to_string(), "Bob".to_string()];\n    users.get(id as usize).cloned()\n}\n\nfn main() {\n    match find_user(0) {\n        Some(name) => println!("उपयोगकर्ता मिला: {}", name),\n        None => println!("उपयोगकर्ता नहीं मिला"),\n    }\n}
\n\n

2. ? ऑपरेटर — try/catch का सुरुचिपूर्ण विकल्प

\n\n

अगर Rust में try/catch होता, तो यह बोझिल दिखता। इसके बजाय, भाषा ? ऑपरेटर प्रदान करती है। यह इस प्रकार काम करता है: यदि परिणाम Ok है, तो मान निकाला जाता है और आगे भेजा जाता है; यदि Err है, तो त्रुटि तुरंत फ़ंक्शन से वापस कर दी जाती है।

\n\n
use std::num::ParseIntError;\n\nfn parse_and_double(input: &str) -> Result<i32, ParseIntError> {\n    let value: i32 = input.parse()?;  // यदि त्रुटि है — तुरंत return Err\n    Ok(value * 2)\n}\n\nfn main() {\n    match parse_and_double("42") {\n        Ok(result) => println!("परिणाम: {}", result),\n        Err(e) => println!("पार्सिंग त्रुटि: {}", e),\n    }\n}
\n\n

? ऑपरेटर का उपयोग केवल उन फ़ंक्शनों में किया जा सकता है जो Result या Option लौटाते हैं। यह डेवलपर को स्पष्ट रूप से इंगित करने के लिए मजबूर करता है कि फ़ंक्शन त्रुटि के साथ समाप्त हो सकता है — Python में अपवादों के विपरीत, जो कहीं से भी "निकल" सकते हैं।

\n\n

3. panic! और unwrap का उपयोग कब करें

\n\n

सभी त्रुटियों को संभालने की आवश्यकता नहीं है। panic! एक मैक्रो है जो पुनर्प्राप्त न करने योग्य त्रुटियों के लिए है। यह प्रोग्राम को रोकता है और स्टैक को अनवाइंड करता है (stack unwind)। इसका उपयोग केवल असाधारण स्थितियों में करें:

\n\n
    \n
  • आपातकालीन स्थितियाँ: इनवेरिएंट का उल्लंघन जिसे ठीक नहीं किया जा सकता।
  • \n
  • उदाहरण और प्रोटोटाइप: शैक्षिक कोड या एक दिवसीय स्क्रिप्ट में।
  • \n
  • परीक्षण: यह जाँचने के लिए कि कोड अपेक्षित स्थानों पर क्रैश होता है।
  • \n
\n\n
fn divide(a: i32, b: i32) -> i32 {\n    if b == 0 {\n        panic!("शून्य से भाग! a={}, b={}", a, b);\n    }\n    a / b\n}
\n\n

unwrap() और expect() का उपयोग तब किया जाता है जब आप पूरी तरह से आश्वस्त हों कि Result या Option में Ok या Some है। यदि कोई त्रुटि होती है, तो unwrap() panic! को ट्रिगर करेगा, और expect() एक कस्टम त्रुटि संदेश के साथ ऐसा करेगा।

ब्लॉग

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