Rust में Generics: क्यों आवश्यक हैं और कैसे उपयोग करें

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

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

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

Rust में Generics का परिचय



सामान्यीकृत प्रोग्रामिंग (generics) Rust की प्रमुख अवधारणाओं में से एक है, जो लचीला, पुन: प्रयोज्य और सुरक्षित कोड लिखने की अनुमति देती है। यदि आप अन्य भाषाओं (जैसे C++ या Java) से Rust पर आ रहे हैं, तो आपने निश्चित रूप से templates या generics का सामना किया होगा। Rust में generics समान रूप से काम करते हैं, लेकिन प्रदर्शन और मेमोरी सुरक्षा पर विशेष जोर देते हैं।



Generics की आवश्यकता क्यों है? कल्पना करें कि आपको एक फ़ंक्शन लिखना है जो सूची में अधिकतम तत्व ढूंढता है। Generics के बिना, आपको i32, f64, String और प्रत्येक उपयोगकर्ता-परिभाषित प्रकार के लिए अलग-अलग संस्करण लिखने होंगे। Generics के साथ, आप एक फ़ंक्शन लिखते हैं जो तुलना का समर्थन करने वाले किसी भी प्रकार के साथ काम करता है।



इस लेख में, हम समझेंगे कि Rust में generics क्या हैं, उन्हें फ़ंक्शन, struct और traits के साथ कैसे उपयोग करें, और व्यावहारिक उदाहरण देखेंगे।



Generics की मूल बातें: फ़ंक्शन और struct



सामान्यीकृत फ़ंक्शन



Generics से परिचित होने का सबसे सरल तरीका एक सामान्यीकृत फ़ंक्शन लिखना है। सिंटैक्स कोणीय कोष्ठक <T> का उपयोग करता है, जहाँ T एक प्रकार पैरामीटर (type parameter) है।



fn largest<T>(list: &[T]) -> &T {    let mut largest = &list[0];    for item in list {        if item > largest {            largest = item;        }    }    largest}

fn main() { let numbers = vec![34, 50, 25, 100, 65]; let result = largest(&numbers); println!("सबसे बड़ी संख्या: {}", result);

let chars = vec!['y', 'm', 'a', 'q']; let result = largest(&chars); println!("सबसे बड़ा अक्षर: {}", result);}


हालाँकि, यह कोड संकलित नहीं होगा! Rust आवश्यकता है कि प्रकार T तुलना के लिए PartialOrd trait को लागू करे। प्रतिबंध (trait bounds) पर हम बाद में विचार करेंगे, अभी के लिए याद रखें: generics आपको विशिष्ट प्रकार से अमूर्त करने की अनुमति देते हैं, लेकिन कंपाइलर को पता होना चाहिए कि कौन से ऑपरेशन अनुमत हैं।



सामान्यीकृत struct



Generics केवल फ़ंक्शन के साथ ही नहीं, बल्कि उपयोगकर्ता-परिभाषित डेटा प्रकारों के साथ भी काम करते हैं। उदाहरण के लिए, निर्देशांक वाला एक बिंदु पूर्णांक या फ़्लोटिंग-पॉइंट संख्याएँ संग्रहीत कर सकता है:



struct Point<T> {    x: T,    y: T,}

fn main() { let integer_point = Point { x: 5, y: 10 }; let float_point = Point { x: 1.0, y: 4.0 }; println!("पूर्णांक बिंदु: ({}, {})", integer_point.x, integer_point.y); println!("फ़्लोटिंग-पॉइंट बिंदु: ({}, {})", float_point.x, float_point.y);}


यदि फ़ील्ड के अलग-अलग प्रकार हैं तो कई प्रकार पैरामीटर का उपयोग किया जा सकता है:



struct Pair<T, U> {    first: T,    second: U,}

fn main() { let pair = Pair { first: 42, second: "उत्तर" }; println!("जोड़ी: {} और {}", pair.first, pair.second);}


Traits और प्रतिबंधों (Trait Bounds) के साथ Generics



Trait bounds क्या हैं?



Trait bounds कंपाइलर को यह बताने का एक तरीका है कि सामान्यीकृत प्रकार को कुछ विशिष्ट traits को लागू करना चाहिए। इनके बिना, हम सामान्यीकृत मान पर विधियाँ नहीं बुला सकते। आइए largest फ़ंक्शन पर वापस जाएँ और इसे ठीक करें:



use std::cmp::PartialOrd;

fn largest<T: PartialOrd>(list: &[T]) -> &T { let mut largest = &list[0]; for item in list { if item > largest { largest = item; } } largest}

fn main() { let numbers = vec![34, 50, 25, 100, 65]; println!("सबसे बड़ा: {}", largest(&numbers));}


अब फ़ंक्शन केवल उन प्रकारों को स्वीकार करता है जो तुलना (PartialOrd) का समर्थन करते हैं।



एकाधिक प्रतिबंध



आप + के माध्यम से कई traits निर्दिष्ट कर सकते हैं। उदाहरण के लिए, प्रकार को एक साथ तुलनीय और क्लोन करने योग्य होना चाहिए:



use std::fmt::Display;

fn print_and_compare ```

ब्लॉग

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