Rust में रिएक्टिव प्रोग्रामिंग: लाइब्रेरी, उदाहरण और अभ्यास

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

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

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

Rust में रिएक्टिव प्रोग्रामिंग: ऑब्जर्वेबल से एसिंक्रोनस स्ट्रीम तक

रिएक्टिव प्रोग्रामिंग एक ऐसी पैराडाइम है जो डेटा के एसिंक्रोनस फ्लो और बदलावों के प्रसार पर केंद्रित है। Rust इकोसिस्टम में, यह शक्तिशाली टाइप सिस्टम, मेमोरी सुरक्षा और आधुनिक एसिंक्रोनस प्रिमिटिव के संयोजन से लागू होती है। इस लेख में, हम Rust में रिएक्टिव प्रोग्रामिंग के लिए प्रमुख लाइब्रेरी, पैटर्न और व्यावहारिक उदाहरण देखेंगे।

Rust में रिएक्टिव प्रोग्रामिंग के लिए मुख्य लाइब्रेरी

Rust में रिएक्टिव प्रोग्रामिंग का कोई एक "मानक" नहीं है, लेकिन कई परिपक्व लाइब्रेरी हैं जो अलग-अलग एब्स्ट्रैक्शन लेवल को कवर करती हैं:

  • RxRust — लोकप्रिय ReactiveX (Rx) का Rust पोर्ट। यह Observable, Observer, Scheduler और ऑपरेटरों (map, filter, flat_map, merge आदि) का विस्तृत सेट प्रदान करता है।
  • futures-rs — एसिंक्रोनस कंप्यूटेशन के लिए मौलिक लाइब्रेरी। Stream trait रिएक्टिव स्ट्रीम का आधार है।
  • async-std और tokio — एसिंक्रोनस रनटाइम जो चैनल, टाइमर और रिएक्टिव चेन के लिए अन्य प्रिमिटिव प्रदान करते हैं।
  • frunk — फंक्शनल प्रोग्रामिंग लाइब्रेरी, जिसमें Lens और State जैसे रिएक्टिव पैटर्न शामिल हैं।

उदाहरण 1: RxRust के साथ सरल Observable

RxRust "ऑब्जर्वर" पैटर्न लागू करता है: Observable इवेंट जनरेट करता है, Observer उन पर सब्सक्राइब करता है।

// Cargo.toml: rxrust = "1.0"
use rxrust::prelude::*;

fn main() {
    let observable = observable::from_iter(vec![1, 2, 3, 4, 5]);

    observable
        .filter(|x| x % 2 == 0)
        .map(|x| x * 10)
        .subscribe(|x| println!("प्राप्त: {}", x));
}

इस उदाहरण में, 1..5 संख्याओं की एक स्ट्रीम बनाई जाती है, सम संख्याओं को फ़िल्टर किया जाता है, 10 से गुणा किया जाता है और प्रिंट किया जाता है। ऑपरेटरों की चेन लेज़ीली (आलसी) निष्पादित होती है — केवल subscribe कॉल करने के बाद।

उदाहरण 2: futures-rs के साथ एसिंक्रोनस स्ट्रीम

futures-rs लाइब्रेरी Stream ट्रेट प्रदान करती है, जो Iterator का एसिंक्रोनस संस्करण है। StreamExt के कॉम्बिनेटर रिएक्टिव चेन बनाने में मदद करते हैं।

// Cargo.toml: futures = "0.3"
use futures::stream::{self, StreamExt};

#[tokio::main]
async fn main() {
    let stream = stream::iter(0..10)
        .filter(|x| futures::future::ready(x % 2 == 0))
        .map(|x| x * 10)
        .take(3);

    let result: Vec<i32> = stream.collect().await;
    println!("परिणाम: {:?}", result); // [0, 20, 40]
}

यहाँ filter एक एसिंक्रोनस फंक्शन लेता है, जिससे चेन के अंदर बाहरी API या डेटाबेस कॉल किए जा सकते हैं। take(3) एलिमेंट की संख्या सीमित करता है — यह "बैकप्रेशर" (backpressure) का एक उदाहरण है।

उदाहरण 3: async-std के साथ रिएक्टिव चैनल

चैनल कंपोनेंट्स के बीच रिएक्टिव इंटरैक्शन लागू करने का एक क्लासिक तरीका है। async-std मल्टी-प्रोड्यूसर, मल्टी-कंज़्यूमर चैनल प्रदान करता है।

// Cargo.toml: async-std = "1.12"
use async_std::channel;
use async_std::task;

#[async_std::main]
async fn main() {
    let (sender, receiver) = channel::unbounded();

    // प्रोड्यूसर
    task::spawn(async move {
        for i in 0..5 {
            sender.send(i).await.unwrap();
            task::sleep(std::time::Duration::from_millis(100)).await;
        }
    });

    // कंज़्यूमर (रिएक्टिव)
    while let Some(msg) = receiver.recv().await {
        println!("प्राप्त: {}", msg);
        if msg == 4 {
            break;
        }
    }
}

चैनल Event Bus, इवेंट बस या कई डेटा स्रोतों वाली सरल रिएक्टिव सिस्टम के लिए आदर्श हैं।

उन्नत पैटर्न: स्ट्रीम का संयोजन

रिएक्टिव प्रोग्रामिंग तब और उपयोगी हो जाती है जब कई डेटा स्रोतों को जोड़ा जाता है।

अनुशंसाएँ