Rust में रिएक्टिव प्रोग्रामिंग: उपकरणों का अवलोकन और कोड उदाहरण
रिएक्टिव प्रोग्रामिंग एक प्रतिमान है जो एसिंक्रोनस डेटा स्ट्रीम और परिवर्तनों के प्रसार पर केंद्रित है। Rust पारिस्थितिकी तंत्र में, इसे RxRust (Reactive Extensions), futures-rs और async-std जैसी शक्तिशाली लाइब्रेरीज़ के माध्यम से कार्यान्वित किया जाता है। ये उपकरण GUI अनुप्रयोगों से लेकर नेटवर्क सेवाओं तक, सुरुचिपूर्ण, दोष-सहिष्णु और उच्च-प्रदर्शन वाली प्रणालियाँ बनाने में सक्षम बनाते हैं। इस लेख में, हम प्रमुख अवधारणाओं को समझेंगे, व्यावहारिक उदाहरण दिखाएंगे और आपके Rust प्रोजेक्ट के लिए उपयुक्त लाइब्रेरी चुनने में मदद करेंगे।
Rust में रिएक्टिव प्रोग्रामिंग के लिए मुख्य लाइब्रेरीज़
Rust में रिएक्टिव प्रोग्रामिंग के लिए सबसे लोकप्रिय लाइब्रेरीज़ में शामिल हैं:
- RxRust — ReactiveX (Rx) का पोर्ट। Observable, Observer, map, filter, merge और अन्य ऑपरेटर प्रदान करता है। इवेंट और डेटा स्ट्रीम को संसाधित करने के लिए आदर्श।
- futures-rs — एसिंक्रोनस गणनाओं के लिए मूल लाइब्रेरी। इसमें Stream, Future, Sink शामिल हैं। कई रिएक्टिव सिस्टम का आधार है।
- async-std — एसिंक्रोनस मानक लाइब्रेरी। फ़ाइल I/O, नेटवर्क ऑपरेशन और रिएक्टिव स्ट्रीम के लिए चैनलों के async संस्करण प्रदान करता है।
- tokio — मल्टीथ्रेडिंग समर्थन के साथ एसिंक्रोनस runtime। रिएक्टिव नेटवर्क अनुप्रयोगों के निर्माण के लिए अक्सर futures-rs के साथ उपयोग किया जाता है।
उदाहरण 1: इवेंट हैंडलिंग के लिए RxRust का उपयोग
RxRust आपको इटरेटर, इवेंट या एसिंक्रोनस स्रोतों से Observable बनाने की अनुमति देता है। नीचे संख्याओं को उत्पन्न करने, फ़िल्टर करने और स्ट्रीम की सदस्यता लेने का एक सरल उदाहरण है:
use rxrust::prelude::*;
fn main() { // संख्याओं की श्रेणी से Observable बनाएँ observable::from_iter(1..10) .filter(|x| x % 2 == 0) // केवल सम संख्याएँ रखें .map(|x| x * 10) // 10 से गुणा करें .subscribe( |x| println!("प्राप्त: {}", x), |err| eprintln!("त्रुटि: {}", err), || println!("स्ट्रीम समाप्त"), );}निष्पादन परिणाम:
प्राप्त: 20प्राप्त: 40प्राप्त: 60प्राप्त: 80स्ट्रीम समाप्तउदाहरण 2: futures-rs के साथ एसिंक्रोनस स्ट्रीम
futures-rs लाइब्रेरी Stream ट्रेट प्रदान करती है, जो Iterator का एसिंक्रोनस एनालॉग है। निम्नलिखित उदाहरण एक स्ट्रीम बनाने, उसे रूपांतरित करने और परिणाम एकत्र करने को दर्शाता है:
use futures::stream::{self, StreamExt};
#[tokio::main]async fn main() { let stream = stream::iter(1..=5) .map(|x| x * x) .filter(|x| futures::future::ready(x % 2 == 0));
let results: Vec<i32> = stream.collect().await; println!("सम संख्याओं के वर्ग: {:?}", results);}आउटपुट:
सम संख्याओं के वर्ग: [4, 16]उदाहरण 3: async-std में रिएक्टिव चैनल
चैनल रिएक्टिव सिस्टम का आधार हैं। async-std लाइब्रेरी मल्टी-यूज़र चैनल प्रदान करती है, जिनका उपयोग कार्यों के बीच इवेंट संचारित करने के लिए किया जा सकता है:
use async_std::sync::channel;use async_std::task;
fn main() { let (sender, receiver) = channel::unbounded::<String>();
// भेजने वाला कार्य task::spawn(async move { sender.send("नमस्ते".to_string()).await.unwrap(); sender.send("दुनिया".to_string()).await.unwrap(); });
// प्राप्त करने वाला कार्य (रिएक्टिव श्रोता) task::block_on(async { while let Some(msg) = receiver.recv().await { println!("संदेश प्राप्त: {}", msg); } });}यह पैटर्न Rust में इवेंट-संचालित अनुप्रयोगों की वास्तुकला का आधार है।