Rust में Generics: शुरुआती लोगों के लिए क्यों ज़रूरी हैं और कैसे उपयोग करें

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

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

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

Rust में Generics: क्यों ज़रूरी हैं और कैसे उपयोग करें

Generics (सामान्यीकरण) Rust की प्रमुख अवधारणाओं में से एक है, जो लचीला, पुन: प्रयोज्य और सुरक्षित कोड लिखने की अनुमति देता है। यदि आप अभी Rust सीखना शुरू कर रहे हैं, तो जेनेरिक्स को समझना कुशल लाइब्रेरी और एप्लिकेशन लिखने का मार्ग खोलता है। इस लेख में, हम जानेंगे कि Generics क्या हैं, वे क्यों ज़रूरी हैं, और व्यवहार में उनका उपयोग कैसे करें।



Generics क्या हैं और वे क्यों ज़रूरी हैं?

कल्पना करें कि आपको एक फ़ंक्शन लिखना है जो किसी सरणी में अधिकतम तत्व ढूंढता है। संख्याओं के लिए एक कार्यान्वयन होगा, स्ट्रिंग्स के लिए दूसरा। प्रत्येक प्रकार के लिए कोड कॉपी करने से बचने के लिए, Rust सामान्यीकृत प्रोग्रामिंग प्रदान करता है Generics की मदद से।

जेनेरिक्स आपको संरचनाओं, फ़ंक्शनों, एनुम या मेथड्स को परिभाषित करने की अनुमति देते हैं जो किसी विशिष्ट प्रकार से बंधे बिना किसी भी डेटा प्रकार के साथ काम करते हैं। कंपाइलर संकलन के समय वास्तविक प्रकार को प्रतिस्थापित करता है - इस प्रक्रिया को मोनोमोर्फ़ाइज़ेशन कहा जाता है।

जेनेरिक्स के बिना, आपको लिखना होगा:

fn max_i32(list: &[i32]) -> i32 {    let mut max = list[0];    for &item in list {        if item > max {            max = item;        }    }    max}

fn max_f64(list: &[f64]) -> f64 { let mut max = list[0]; for &item in list { if item > max { max = item; } } max}

जेनेरिक्स के साथ, यह एक सार्वभौमिक फ़ंक्शन में बदल जाता है।



Generics के उपयोग की मूल बातें

Generic-फ़ंक्शन

किसी फ़ंक्शन को सामान्यीकृत बनाने के लिए, आपको कोण कोष्ठक <T> में प्रकार पैरामीटर निर्दिष्ट करना होगा:

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

लेकिन यह कोड संकलित नहीं होगा - कंपाइलर कहेगा कि प्रकार T के लिए ट्रेट PartialOrd लागू नहीं किया गया है। यहीं पर ट्रेट-बाधाएं काम आती हैं।



Generic-संरचनाएं और एनुम

संरचनाएं भी सामान्यीकृत हो सकती हैं:

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

fn main() { let int_point = Point { x: 5, y: 10 }; let float_point = Point { x: 1.5, y: 3.8 };}

आप कई प्रकार के पैरामीटर निर्दिष्ट कर सकते हैं:

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

एनुम भी जेनेरिक्स का समर्थन करते हैं - मानक लाइब्रेरी से Option<T> या Result<T, E> याद रखें।



Generic-मेथड्स

जेनेरिक्स वाली संरचनाओं के लिए मेथड्स परिभाषित किए जा सकते हैं:

impl<T> Point<T> {    fn x(&self) -> &T {        &self.x    }}

या केवल एक विशिष्ट प्रकार के लिए:

impl Point<f64> {    fn distance_from_origin(&self) -> f64 {        (self.x.powi(2) + self.y.powi(2)).sqrt()    }}


ट्रेट बाधाएं (Trait Bounds)

तुलना, जोड़ या अन्य मेथड्स का उपयोग करने के लिए, आपको यह निर्दिष्ट करना होगा कि प्रकार कौन से ट्रेट्स लागू करता है। आइए max फ़ंक्शन पर वापस आते हैं:

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

अब कोड संकलित होता है - हमने कहा कि T को आंशिक क्रम (PartialOrd) का समर्थन करना चाहिए।

आप + के माध्यम से ट्रेट्स को जोड़ सकते हैं:

fn clone_and_compare<T: Clone + PartialOrd>(a: T, b: T) -> bool {    a.clone() > b.clone()}

या पठनीयता के लिए where सिंटैक्स का उपयोग करें:

fn some_function<T, U>(t: &T, u: &U) -> i32where    T:                

ब्लॉग

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