Rust वैरिएबल्स और डेटा प्रकार (Variables and Data Types in Rust)

Rust वैरिएबल्स और डेटा प्रकार (Variables and Data Types in Rust)

Rust प्रोग्रामिंग भाषा में वैरिएबल्स और डेटा प्रकारों की समझ प्रोग्रामिंग की मूलभूत नींव है। इस लेख में, हम Rust में वैरिएबल्स के प्रकार, Immutable और Mutable वैरिएबल्स के बीच अंतर, और विभिन्न डेटा प्रकारों का उपयोग कैसे किया जाता है, इसके बारे में जानेंगे। इसके अलावा, हम टाइप एनोटेशन और इसका सही उपयोग भी सीखेंगे, जिससे आपके प्रोग्राम्स अधिक सुरक्षित और प्रभावी बन सकें।

अगर आप Rust की दुनिया में नए हैं, तो यह लेख आपके लिए एक ठोस नींव तैयार करेगा। आइए, विस्तार से समझते हैं Rust में वैरिएबल्स और डेटा प्रकार।

Rust में वैरिएबल्स (Variables in Rust)

Rust प्रोग्रामिंग भाषा में, वैरिएबल्स का उपयोग किसी डेटा को स्टोर करने के लिए किया जाता है जिसे बाद में प्रोग्राम के दौरान एक्सेस या संशोधित किया जा सके। हालांकि, Rust की खास बात यह है कि डिफ़ॉल्ट रूप से वैरिएबल्स immutable होते हैं, यानी एक बार वैरिएबल को कोई मान असाइन कर दिया जाए, तो उसे बदला नहीं जा सकता। अगर आपको वैरिएबल का मान बदलने की आवश्यकता है, तो आपको उसे mutable के रूप में घोषित करना होगा।

Immutable वैरिएबल्स (Immutable Variables)

डिफ़ॉल्ट रूप से, Rust में हर वैरिएबल immutable होता है। इसका मतलब यह है कि एक बार किसी वैरिएबल को कोई मान दे दिया गया, तो उसे बदलने का प्रयास करने पर प्रोग्राम कम्पाइल नहीं होगा।

fn main() {
    let x = 10;
    println!("x का मान है: {}", x);
    
    // निम्नलिखित लाइन एरर देगी क्योंकि x को दोबारा असाइन किया जा रहा है
    x = 20;
}

ऊपर दिए गए उदाहरण में, let कीवर्ड के साथ वैरिएबल x को 10 का मान दिया गया है। लेकिन जब हम इसे फिर से 20 असाइन करने का प्रयास करते हैं, तो यह एरर देगा क्योंकि वैरिएबल को दोबारा असाइन करना वैध नहीं है।

Mutable वैरिएबल्स (Mutable Variables)

अगर आपको वैरिएबल के मान को बदलने की जरूरत है, तो आपको वैरिएबल को mut कीवर्ड के साथ घोषित करना होगा। यह Rust को यह बताता है कि आप इस वैरिएबल को बदलना चाहते हैं।

fn main() {
    let mut x = 10;
    println!("शुरुआत में x का मान है: {}", x);
    
    // अब हम x को नया मान असाइन कर सकते हैं
    x = 20;
    println!("अब x का नया मान है: {}", x);
}

यहाँ, हमने x को mut कीवर्ड के साथ घोषित किया है, जिससे हम इसके मान को बदल सकते हैं। इस कोड के आउटपुट में पहले x का मान 10 होगा, और फिर इसे 20 में बदलकर प्रिंट किया जाएगा।

डेटा प्रकार (Primitive Data Types)

Rust में डेटा प्रकार (Data Types) यह निर्धारित करते हैं कि वैरिएबल किस प्रकार का डेटा स्टोर करेगा। Rust एक strongly typed भाषा है, जिसका मतलब है कि हर वैरिएबल और एक्सप्रेशन का एक निश्चित डेटा प्रकार होता है। Rust के प्राथमिक (primitive) डेटा प्रकारों का उपयोग बेसिक ऑपरेशन्स के लिए किया जाता है, और यह काफी कुशल होते हैं।

Rust में मुख्यतः निम्नलिखित प्राइमिटिव डेटा प्रकार होते हैं:

1. संख्यात्मक प्रकार (Numerical Types)

Rust में संख्याओं के दो प्रमुख प्रकार होते हैं:

  • Integer (पूर्णांक संख्याएँ)
  • Floating Point (दशमलव संख्याएँ)
Integer Types

Integer प्रकार पूरी संख्याओं का प्रतिनिधित्व करता है। ये signed (धनात्मक और ऋणात्मक दोनों) और unsigned (सिर्फ धनात्मक) हो सकते हैं।

डेटा प्रकारबाइट्स में आकारमान की सीमा (signed)मान की सीमा (unsigned)
i81 बाइट-128 से 1270 से 255
i162 बाइट-32,768 से 32,7670 से 65,535
i324 बाइट-2,147,483,648 से 2,147,483,6470 से 4,294,967,295
i648 बाइट-9,223,372,036,854,775,808 से 9,223,372,036,854,775,807
Floating Point Types

Floating-point प्रकार दशमलव संख्याओं का प्रतिनिधित्व करता है। Rust में दो प्रकार की floating-point संख्याएँ होती हैं:

  • f32 (32-बिट फ्लोट)
  • f64 (64-बिट फ्लोट, जो डिफ़ॉल्ट है)
    fn main() {
        let x: i32 = 10;  // Signed integer
        let y: u8 = 255;  // Unsigned integer
        let z: f64 = 3.14; // Floating point number
    
        println!("x का मान है: {}", x);
        println!("y का मान है: {}", y);
        println!("z का मान है: {}", z);
    }
    

     

2. बूलियन प्रकार (Boolean Type)

Rust में बूलियन प्रकार (Boolean Type) सिर्फ दो मान ले सकता है: true या false। यह प्रकार अक्सर नियंत्रण संरचनाओं (जैसे कि if-else) में उपयोग किया जाता है।

fn main() {
    let is_rust_fun: bool = true;

    if is_rust_fun {
        println!("हाँ, Rust मजेदार है!");
    }
}

3. कैरेक्टर प्रकार (Character Type)

Rust का char प्रकार एक Unicode कैरेक्टर का प्रतिनिधित्व करता है। इसका मतलब है कि यह केवल ASCII कैरेक्टर्स (जैसे ‘a’ या ‘@’) को ही नहीं, बल्कि Emoji और अन्य भाषाओं के कैरेक्टर्स को भी स्टोर कर सकता है।

fn main() {
    let letter: char = 'A';
    let emoji: char = '😊';

    println!("letter: {}", letter);
    println!("emoji: {}", emoji);
}

4. ट्यूपल्स (Tuples)

ट्यूपल्स एक समूह में विभिन्न प्रकार के डेटा को एक साथ रखने का तरीका है। यह डेटा प्रकारों के एक स्थिर सेट का प्रतिनिधित्व करता है। ट्यूपल्स में विभिन्न प्रकार के डेटा प्रकार हो सकते हैं।

fn main() {
    let person: (i32, f64, char) = (25, 6.2, 'M');
    let (age, height, gender) = person;

    println!("उम्र: {}, ऊँचाई: {}, लिंग: {}", age, height, gender);
}

5. ऐरे (Arrays)

Rust में ऐरे एक समान प्रकार के डेटा के निश्चित आकार के संग्रह का प्रतिनिधित्व करते हैं। ऐरे का आकार स्थिर होता है और इसे एक बार परिभाषित करने के बाद नहीं बदला जा सकता।

fn main() {
    let numbers: [i32; 4] = [1, 2, 3, 4];

    for number in numbers.iter() {
        println!("संख्या: {}", number);
    }
}

Immutable और Mutable वैरिएबल्स (Immutable vs Mutable Variables)

Rust की सबसे खास विशेषताओं में से एक है इसका ध्यान immutability (अपरिवर्तनीयता) पर। डिफ़ॉल्ट रूप से, Rust में सभी वैरिएबल्स immutable होते हैं, जिसका मतलब यह है कि एक बार किसी वैरिएबल को कोई मान असाइन कर दिया गया, तो आप उसे बाद में बदल नहीं सकते। अगर आपको वैरिएबल के मान को बदलने की जरूरत होती है, तो आप उसे mutable घोषित कर सकते हैं। आइए इन दोनों प्रकार के वैरिएबल्स के बीच अंतर और उनके उपयोग को विस्तार से समझते हैं।

Immutable वैरिएबल्स (Immutable Variables)

जब आप Rust में एक वैरिएबल बनाते हैं और उसे डिफ़ॉल्ट रूप से असाइन करते हैं, तो वह immutable होता है। इसका मतलब है कि उस वैरिएबल का मान पूरी प्रोग्राम की अवधि में नहीं बदलेगा। यह Rust में सुरक्षा को बढ़ाता है क्योंकि यह अनजाने में मान को बदलने से रोकता है, जिससे संभावित बग्स और गलतियाँ कम होती हैं।

उदाहरण:

fn main() {
    let x = 10;
    println!("x का प्रारंभिक मान है: {}", x);

    // यह कोड एरर देगा क्योंकि x को दोबारा असाइन करने की अनुमति नहीं है
    x = 20;
}

ऊपर दिए गए कोड में, वैरिएबल x को 10 का मान असाइन किया गया है। इसके बाद, जब हम इसे दोबारा 20 से बदलने का प्रयास करते हैं, तो Rust कम्पाइलर एरर देगा, क्योंकि x को immutable के रूप में घोषित किया गया था। अगर आप मान को बदलना चाहते हैं, तो इसे mut कीवर्ड के साथ mutable घोषित करना होगा।

Mutable वैरिएबल्स (Mutable Variables)

अगर आपको किसी वैरिएबल का मान बदलने की आवश्यकता है, तो Rust आपको उसे mutable बनाने का विकल्प देता है। जब आप किसी वैरिएबल को mut कीवर्ड के साथ घोषित करते हैं, तो आप उसके मान को बाद में बदल सकते हैं। यह flexibility उन स्थितियों में काम आता है जहां आपको वैरिएबल्स के मान को बार-बार संशोधित करने की आवश्यकता होती है।

उदाहरण:

fn main() {
    let mut x = 10;
    println!("शुरुआत में x का मान है: {}", x);

    // अब हम x का मान बदल सकते हैं
    x = 20;
    println!("बदले जाने के बाद x का मान है: {}", x);
}

इस उदाहरण में, x को mut कीवर्ड के साथ घोषित किया गया है, जिससे हम इसके मान को 10 से 20 में बदल सकते हैं। यह flexibility उस समय बहुत उपयोगी होती है जब वैरिएबल्स के मान को बार-बार बदलने की जरूरत होती है।

Immutable vs Mutable: कब क्या चुनें?

  1. Immutable वैरिएबल्स का उपयोग करें:
    • जब आपको यकीन हो कि वैरिएबल का मान प्रोग्राम के दौरान कभी नहीं बदलेगा।
    • Immutable वैरिएबल्स का उपयोग कोड को अधिक स्थिर और भविष्य में त्रुटियों से मुक्त बनाता है।
    • यह सुरक्षा बढ़ाता है और अनपेक्षित बदलावों से बचाता है।
  2. Mutable वैरिएबल्स का उपयोग करें:
    • जब आपको वैरिएबल के मान को बार-बार बदलने की आवश्यकता हो।
    • Mutable वैरिएबल्स को सही तरीके से प्रबंधित करना महत्वपूर्ण है ताकि यह स्पष्ट हो कि कहां और क्यों आप मान को बदल रहे हैं।

टाइप एनोटेशन (Type Annotations)

Rust एक statically typed भाषा है, जिसका मतलब है कि हर वैरिएबल का एक निश्चित डेटा प्रकार होना चाहिए, जिसे कम्पाइल के समय जाना जाता है। हालांकि Rust में टाइप इंफरेंस (type inference) होता है, यानी Rust स्वचालित रूप से वैरिएबल के प्रकार का अनुमान लगा सकता है, लेकिन कभी-कभी आपको टाइप एनोटेशन (type annotations) का उपयोग करने की आवश्यकता होती है, ताकि कोड अधिक स्पष्ट और समझने में आसान हो सके, या विशेष प्रकार का डेटा स्टोर किया जा सके।

टाइप एनोटेशन यह सुनिश्चित करता है कि वैरिएबल का डेटा प्रकार स्पष्ट रूप से परिभाषित है, जिससे बाद में किसी भी प्रकार के भ्रम या त्रुटियों से बचा जा सकता है।

टाइप एनोटेशन का उपयोग (Using Type Annotations)

जब आप टाइप एनोटेशन का उपयोग करते हैं, तो वैरिएबल को घोषित करते समय आपको उसके डेटा प्रकार को भी बताना पड़ता है। यह करने के लिए आप वैरिएबल के नाम के बाद कोलन (:) और फिर डेटा प्रकार लिखते हैं।

उदाहरण:

fn main() {
    let x: i32 = 5;  // x एक 32-बिट signed integer है
    let y: f64 = 3.14;  // y एक 64-बिट floating-point संख्या है

    println!("x का मान है: {}", x);
    println!("y का मान है: {}", y);
}

ऊपर दिए गए उदाहरण में, हमने x और y वैरिएबल्स के प्रकार स्पष्ट रूप से बताए हैं: x को i32 (32-बिट signed integer) और y को f64 (64-बिट floating-point) के रूप में घोषित किया है। Rust इस प्रकार के अनुसार वैरिएबल्स को संभालता है।

कब टाइप एनोटेशन की आवश्यकता होती है?

  1. टाइप इंफरेंस विफल होने पर: Rust की टाइप इंफरेंस प्रणाली बहुत प्रभावी है, लेकिन कुछ मामलों में Rust वैरिएबल का प्रकार निर्धारित नहीं कर पाता। उदाहरण के लिए, जब आप एक खाली वैक्टर या एक जटिल गणना करते हैं, तो आपको टाइप एनोटेशन का उपयोग करना होगा।उदाहरण:
    fn main() {
        let numbers: Vec<i32> = Vec::new();  // यहाँ टाइप एनोटेशन आवश्यक है
    }
    

     

  2. स्पष्टता के लिए: जब कोड बहुत जटिल हो, तो टाइप एनोटेशन का उपयोग करने से यह स्पष्ट हो जाता है कि कौन सा वैरिएबल किस प्रकार का डेटा स्टोर कर रहा है। इससे कोड पढ़ने वाले अन्य लोगों को इसे समझने में आसानी होती है।
  3. डिफ़ॉल्ट प्रकार से भिन्न प्रकार का उपयोग करना: कुछ मामलों में, Rust स्वचालित रूप से एक प्रकार का अनुमान लगाता है, लेकिन यदि आप कोई विशेष प्रकार चाहते हैं, तो आपको टाइप एनोटेशन देना होगा। उदाहरण के लिए, floating-point संख्या के लिए Rust स्वचालित रूप से f64 का अनुमान लगाता है, लेकिन यदि आप f32 चाहते हैं, तो आपको टाइप एनोटेशन का उपयोग करना होगा।उदाहरण:
    fn main() {
        let pi: f32 = 3.14;  // डिफ़ॉल्ट `f64` नहीं, बल्कि `f32` के रूप में घोषित
    }
    

     

साधारण टाइप इंफरेंस (Simple Type Inference)

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

उदाहरण:

fn main() {
    let name = "Rust";  // Rust स्वचालित रूप से इसे &str (string slice) मानता है
    let age = 30;       // Rust इसे i32 मानता है (डिफ़ॉल्ट signed integer)
}

इस उदाहरण में, हमने टाइप एनोटेशन नहीं दिया है, लेकिन Rust ने स्वतः ही name को &str और age को i32 माना है।



Index