Full program of Go (Golang) code

Go (Golang) संपूर्ण गाइड

Go (Golang) भाषा: एक संपूर्ण गाइड

Go, जिसे अक्सर Golang भी कहा जाता है, गूगल द्वारा विकसित एक स्टेटिकली टाइप्ड, कंपाइल्ड प्रोग्रामिंग भाषा है। इसे सादगी, दक्षता, विश्वसनीयता और समवर्ती (Concurrent) प्रोग्रामिंग के लिए आसान समर्थन प्रदान करने के लिए डिज़ाइन किया गया है। यह आधुनिक सॉफ्टवेयर विकास, विशेष रूप से बड़े पैमाने पर सिस्टम, नेटवर्क सेवाओं और क्लाउड-आधारित अनुप्रयोगों के लिए तेजी से लोकप्रिय हो रहा है।

1. गो क्या है और इसका उपयोग क्यों किया जाता है?

Go एक ओपन-सोर्स प्रोग्रामिंग भाषा है जिसे रॉबर्ट ग्रिसमर, रॉब पाइक और केन थॉम्पसन ने Google में विकसित किया था। इसका लक्ष्य मौजूदा भाषाओं (जैसे C++, Java) की कुछ जटिलताओं को दूर करना और आधुनिक हार्डवेयर (मल्टी-कोर प्रोसेसर) और नेटवर्क वातावरण के लिए बेहतर समाधान प्रदान करना था।

इसका उपयोग क्यों किया जाता है?

  • सरलता (Simplicity): इसका सिंटैक्स साफ और सीखने में आसान है।
  • दक्षता (Efficiency): यह कंपाइल होकर नेटिव मशीन कोड बनाता है, जिससे यह C/C++ के समान तेज़ प्रदर्शन देता है।
  • कनकरेंसी (Concurrency): Goroutines और Channels के माध्यम से कनकरेंट प्रोग्रामिंग को आसान बनाता है।
  • तेज कंपाइलेशन (Fast Compilation): बड़े प्रोजेक्ट्स भी जल्दी कंपाइल होते हैं।
  • स्टेटिक टाइपिंग (Static Typing): कंपाइल समय पर टाइप एरर पकड़ता है, जिससे रनटाइम बग कम होते हैं।
  • गार्बेज कलेक्शन (Garbage Collection): स्वचालित मेमोरी प्रबंधन विकास को सरल बनाता है।
  • उत्कृष्ट मानक लाइब्रेरी (Standard Library): नेटवर्किंग, वेब सर्वर, क्रिप्टोग्राफी आदि के लिए मजबूत लाइब्रेरी।
  • अच्छा टूलिंग (Good Tooling): फॉर्मेटिंग (gofmt), टेस्टिंग (go test), निर्भरता प्रबंधन (Go Modules) के लिए अंतर्निहित उपकरण।

2. गो की विशेषताएं क्या हैं?

ऊपर बताए गए फायदों के अलावा, गो की कुछ प्रमुख विशेषताएं हैं:

  • सादगी और पठनीयता (Simplicity & Readability): कम कीवर्ड और सीधा सिंटैक्स।
  • कनकरेंसी सपोर्ट: भाषा में निर्मित Goroutines और Channels
  • मेमोरी सुरक्षा: गार्बेज कलेक्शन और टाइप सेफ्टी।
  • तेज कंपाइलेशन: बड़े कोडबेस के लिए भी तेज।
  • प्लेटफ़ॉर्म स्वतंत्रता: विभिन्न ऑपरेटिंग सिस्टम और आर्किटेक्चर के लिए क्रॉस-कंपाइलेशन आसान है।
  • शक्तिशाली मानक लाइब्रेरी: वेब, नेटवर्किंग, एन्कोडिंग, क्रिप्टोग्राफी आदि के लिए बिल्ट-इन पैकेज।
  • Go Modules: आधुनिक निर्भरता प्रबंधन प्रणाली।

3. गो के विकास का इतिहास क्या है?

  • 2007: Google में रॉबर्ट ग्रिसमर, रॉब पाइक और केन थॉम्पसन द्वारा डिजाइन शुरू किया गया।
  • उद्देश्य: Google के बड़े पैमाने पर सॉफ्टवेयर इंजीनियरिंग चुनौतियों का समाधान करना, जैसे धीमी बिल्ड, अनियंत्रित निर्भरताएँ, और समवर्ती प्रोग्रामिंग में कठिनाई।
  • नवंबर 2009: इसे ओपन सोर्स प्रोजेक्ट के रूप में सार्वजनिक रूप से घोषित किया गया।
  • मार्च 2012: Go संस्करण 1.0 (Go 1) जारी किया गया, जिसने भाषा और मानक लाइब्रेरी के लिए स्थिरता की गारंटी दी।
  • उसके बाद: नियमित रूप से नए संस्करण जारी किए गए हैं, जिनमें प्रदर्शन सुधार, नई सुविधाएँ और लाइब्रेरी अपडेट शामिल हैं। Go Modules को Go 1.11 में पेश किया गया था।

4. गो का सिंटैक्स कैसा है?

Go का सिंटैक्स C परिवार (C, C++, Java, C#) से प्रेरित है, लेकिन इसे सरल बनाया गया है।

  • पैकेज घोषणा: हर Go फ़ाइल एक package घोषणा से शुरू होती है (एक्जीक्यूटेबल के लिए package main)।
  • इम्पोर्ट स्टेटमेंट: अन्य पैकेज का उपयोग करने के लिए import
  • फ़ंक्शन: func कीवर्ड का उपयोग करके परिभाषित किए जाते हैं। मुख्य फ़ंक्शन func main() है।
  • सेमीकोलन (;): अधिकांश स्टेटमेंट्स के अंत में आवश्यक नहीं हैं; कंपाइलर उन्हें स्वचालित रूप से जोड़ता है।
  • संक्षिप्त वेरिएबल घोषणा: := ऑपरेटर का उपयोग फ़ंक्शन के अंदर टाइप अनुमान के साथ वेरिएबल घोषित करने और इनिशियलाइज़ करने के लिए किया जा सकता है।

उदाहरण: हैलो, वर्ल्ड!



package main // प्रोग्राम का पैकेज main होना चाहिए

import "fmt" // फॉर्मेटिंग और प्रिंटिंग के लिए fmt पैकेज इम्पोर्ट करें

func main() { // प्रोग्राम का एंट्री पॉइंट

    fmt.Println("नमस्ते, दुनिया!") // कंसोल पर टेक्स्ट प्रिंट करें

}

5. गो में वेरिएबल और डेटा टाइप कैसे उपयोग करें?

वेरिएबल डेटा को स्टोर करने के लिए उपयोग किए जाते हैं। Go एक स्टेटिकली टाइप्ड भाषा है, जिसका अर्थ है कि वेरिएबल का प्रकार कंपाइल समय पर ज्ञात होता है।

वेरिएबल घोषणा (Variable Declaration)

  • var कीवर्ड के साथ:
    
    
    var age int // उम्र नाम का इंटीजर वेरिएबल घोषित किया
    
    age = 30    // मान असाइन किया
    
    var name string = "एलिस" // स्ट्रिंग वेरिएबल घोषित और इनिशियलाइज़ किया
    
    var score = 95.5 // टाइप अनुमान (float64)
    
            
  • संक्षिप्त घोषणा (:=) (केवल फ़ंक्शन के अंदर):
    
    
    func example() {
    
        message := "यह एक संदेश है" // स्ट्रिंग टाइप अनुमानित
    
        count := 10               // इंट टाइप अनुमानित
    
        isActive := true          // बूलियन टाइप अनुमानित
    
        fmt.Println(message, count, isActive)
    
    }
    
            

मूल डेटा टाइप्स (Basic Data Types)

  • Integers (पूर्णांक): int, int8, int16, int32, int64, uint, uint8, etc. int का आकार आमतौर पर 32 या 64 बिट होता है जो आर्किटेक्चर पर निर्भर करता है।
  • Floating-point numbers (फ़्लोटिंग-पॉइंट): float32, float64.
  • Booleans (बूलियन): bool (मान: true या false).
  • Strings (स्ट्रिंग): string (बाइट्स का अपरिवर्तनीय क्रम, आमतौर पर UTF-8 एन्कोडेड टेक्स्ट)।
  • Complex numbers (सम्मिश्र संख्याएँ): complex64, complex128.

अन्य महत्वपूर्ण प्रकार:

  • Arrays (ऐरे): निश्चित आकार के समान प्रकार के तत्वों का संग्रह।
  • Slices (स्लाइस): ऐरे के ऊपर एक लचीला, गतिशील दृश्य (सबसे अधिक इस्तेमाल किया जाने वाला)।
  • Maps (मैप): कुंजी-मान युग्मों का एक अनऑर्डर्ड संग्रह (हैश टेबल)।
  • Structs (स्ट्रक्ट): विभिन्न प्रकार के फ़ील्ड्स का संग्रह (कस्टम डेटा संरचना)।
  • Pointers (पॉइंटर्स): मेमोरी एड्रेस स्टोर करते हैं।
  • Interfaces (इंटरफ़ेस): मेथड सिग्नेचर का एक सेट परिभाषित करते हैं।
  • Channels (चैनल): गोरूटीन के बीच संचार के लिए।

6. गो में फंक्शन और पैकेज कैसे उपयोग करें?

फंक्शन्स (Functions)

फ़ंक्शन कोड के ब्लॉक होते हैं जिन्हें नाम दिया जाता है और बार-बार उपयोग किया जा सकता है।



package main

import "fmt"

// सरल फ़ंक्शन बिना पैरामीटर और रिटर्न मान के

func greet() {

    fmt.Println("नमस्कार!")

}

// पैरामीटर के साथ फ़ंक्शन

func greetPerson(name string) {

    fmt.Println("नमस्ते,", name)

}

// पैरामीटर और रिटर्न मान के साथ फ़ंक्शन

func add(a int, b int) int {

    return a + b

}

// एकाधिक मान रिटर्न करना

func divide(a, b float64) (float64, error) {

    if b == 0 {

        return 0, fmt.Errorf("शून्य से विभाजित नहीं कर सकते")

    }

    return a / b, nil // परिणाम और nil एरर

}

func main() {

    greet() // आउटपुट: नमस्कार!

    greetPerson("बॉब") // आउटपुट: नमस्ते, बॉब

    

    sum := add(5, 3)

    fmt.Println("योग:", sum) // आउटपुट: योग: 8

    result, err := divide(10.0, 2.0)

    if err != nil {

        fmt.Println("त्रुटि:", err)

    } else {

        fmt.Println("परिणाम:", result) // आउटपुट: परिणाम: 5.0

    }

    _, err = divide(5.0, 0.0) // परिणाम को अनदेखा करें

    if err != nil {

        fmt.Println("त्रुटि:", err) // आउटपुट: त्रुटि: शून्य से विभाजित नहीं कर सकते

    }

}

पैकेजेज (Packages)

पैकेज Go में कोड को व्यवस्थित करने का तरीका है। प्रत्येक Go फ़ाइल एक पैकेज से संबंधित होती है।

  • मुख्य पैकेज (main): एक निष्पादन योग्य प्रोग्राम बनाता है। इसमें main फ़ंक्शन होना चाहिए।
  • अन्य पैकेज (लाइब्रेरी): पुन: प्रयोज्य कोड प्रदान करते हैं।
  • निर्यात (Exporting): पैकेज के बाहर से एक्सेस किए जा सकने वाले नाम (फ़ंक्शन, वेरिएबल, टाइप) बड़े अक्षर से शुरू होने चाहिए। छोटे अक्षर से शुरू होने वाले नाम पैकेज के लिए निजी होते हैं।
  • आयात (Importing): import कीवर्ड का उपयोग करके अन्य पैकेजों को आयात किया जाता है।

उदाहरण: कस्टम पैकेज बनाना

मान लीजिए आपकी प्रोजेक्ट संरचना है:


myproject/

├── main.go

└── calculator/

    └── calc.go

calculator/calc.go:



package calculator // पैकेज का नाम

// Add फ़ंक्शन (बड़ा 'A' इसे निर्यात करता है)

func Add(a, b int) int {

    return a + b

}

// subtract फ़ंक्शन (छोटा 's' इसे निजी रखता है)

func subtract(a, b int) int {

    return a - b

}

main.go:



package main

import (

    "fmt"

    "myproject/calculator" // अपने मॉड्यूल पथ का उपयोग करें

)

func main() {

    x := 10

    y := 5

    sum := calculator.Add(x, y) // निर्यातित फ़ंक्शन का उपयोग करें

    fmt.Println("योग:", sum) 

    // diff := calculator.subtract(x, y) // यह काम नहीं करेगा (संकलन त्रुटि)

    // fmt.Println("अंतर:", diff)

}

(नोट: इस उदाहरण को चलाने के लिए, आपको myproject डायरेक्टरी में go mod init myproject चलाना होगा)

7. गो में कनकरेंसी क्या है और इसका उपयोग कैसे करें?

कनकरेंसी (Concurrency) का अर्थ है एक ही समय में कई कार्यों का प्रबंधन करना। यह पैरेललिज्म (Parallelism) से अलग है, जिसका अर्थ है एक ही समय में कई कार्यों को *करना* (आमतौर पर मल्टी-कोर प्रोसेसर पर)। Go कनकरेंसी को अपनी मुख्य विशेषताओं में से एक के रूप में डिज़ाइन किया गया है, जिससे डेवलपर्स आसानी से ऐसे प्रोग्राम बना सकते हैं जो एक साथ कई काम कर सकें।

Go कनकरेंसी के लिए दो मुख्य तंत्रों का उपयोग करता है:

  1. Goroutines: हल्के, समवर्ती फ़ंक्शन।
  2. Channels: गोरूटीन के बीच संचार और सिंक्रनाइज़ेशन के लिए टाइप की गई नलिकाएँ।

इसका उपयोग I/O-बाउंड कार्यों (जैसे नेटवर्क अनुरोध, फ़ाइल पढ़ना/लिखना) या CPU-बाउंड कार्यों को कुशलतापूर्वक संभालने के लिए किया जाता है, जिससे एप्लिकेशन अधिक प्रतिक्रियाशील और तेज़ बनते हैं।

8. गो में गोरूटीन और चैनल कैसे उपयोग करें?

गोरूटीन (Goroutines)

गोरूटीन एक फ़ंक्शन है जो अन्य फ़ंक्शन के साथ समवर्ती रूप से चल सकता है। यह पारंपरिक थ्रेड्स की तुलना में बहुत हल्का होता है। गोरूटीन शुरू करने के लिए फ़ंक्शन कॉल से पहले go कीवर्ड का उपयोग करें।



package main

import (

    "fmt"

    "time"

)

func say(s string) {

    for i := 0; i < 3; i++ {

        fmt.Println(s)

        time.Sleep(100 * time.Millisecond)

    }

}

func main() {

    go say("World") // गोरूटीन शुरू करें

    say("Hello")   // मुख्य गोरूटीन में चलाएं

    // आउटपुट (क्रम भिन्न हो सकता है):

    // Hello

    // World

    // Hello

    // World

    // Hello

    // World 

    

    // ध्यान दें: यदि main() गोरूटीन खत्म हो जाता है, तो अन्य गोरूटीन भी रुक जाते हैं।

    // वास्तविक अनुप्रयोगों में, आपको प्रतीक्षा करने के लिए सिंक्रनाइज़ेशन की आवश्यकता होगी।

}

चैनल (Channels)

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

  • बनाना: ch := make(chan int) (बिना बफर वाला इंटीजर चैनल)
  • भेजना: ch <- value (चैनल पर मान भेजें)
  • प्राप्त करना: value := <- ch (चैनल से मान प्राप्त करें)

भेजना और प्राप्त करना डिफ़ॉल्ट रूप से ब्लॉक होता है जब तक कि दूसरा पक्ष तैयार न हो। यह सिंक्रनाइज़ेशन का एक रूप है।



package main

import "fmt"

func sum(s []int, c chan int) {

    sum := 0

    for _, v := range s {

        sum += v

    }

    c <- sum // योग को चैनल c पर भेजें

}

func main() {

    s := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int) // एक इंटीजर चैनल बनाएं

    

    // स्लाइस को दो हिस्सों में बांटें और प्रत्येक के लिए एक गोरूटीन में योग करें

    go sum(s[:len(s)/2], c) // पहला आधा हिस्सा

    go sum(s[len(s)/2:], c) // दूसरा आधा हिस्सा

    // चैनल से दो परिणाम प्राप्त करें

    x := <-c 

    y := <-c 

    fmt.Println("पहला योग:", x)

    fmt.Println("दूसरा योग:", y)

    fmt.Println("कुल योग:", x + y)

}

9. गो में सिंक्रोनाइजेशन प्रिमिटिव्स कैसे उपयोग करें?

चैनलों के अलावा, Go का sync पैकेज पारंपरिक सिंक्रोनाइज़ेशन प्रिमिटिव्स भी प्रदान करता है, खासकर जब साझा मेमोरी तक पहुंच को नियंत्रित करने की आवश्यकता होती है।

Mutex (म्यूचुअल एक्सक्लूजन)

sync.Mutex का उपयोग कोड के एक महत्वपूर्ण खंड (critical section) को लॉक करने के लिए किया जाता है ताकि एक समय में केवल एक गोरूटीन ही उस तक पहुंच सके। यह साझा डेटा को रेस कंडीशन से बचाता है।



package main

import (

    "fmt"

    "sync"

    "time"

)

// सुरक्षित काउंटर

type SafeCounter struct {

    mu sync.Mutex // म्यूटेक्स

    v  map[string]int

}

// मान बढ़ाने के लिए (सुरक्षित)

func (c *SafeCounter) Inc(key string) {

    c.mu.Lock() // लॉक करें

    // लॉक होने के बाद ही मैप एक्सेस करें

    c.v[key]++

    c.mu.Unlock() // अनलॉक करें

}

// मान प्राप्त करने के लिए (सुरक्षित)

func (c *SafeCounter) Value(key string) int {

    c.mu.Lock() // लॉक करें

    // लॉक को डेफर करके अनलॉक करना सुनिश्चित करें

    defer c.mu.Unlock()

    return c.v[key]

}

func main() {

    c := SafeCounter{v: make(map[string]int)}

    var wg sync.WaitGroup // WaitGroup का उपयोग करें

    for i := 0; i < 1000; i++ {

        wg.Add(1) // प्रत्येक गोरूटीन के लिए काउंटर बढ़ाएं

        go func() {

            defer wg.Done() // गोरूटीन समाप्त होने पर काउंटर घटाएं

            c.Inc("somekey")

        }()

    }

    wg.Wait() // सभी गोरूटीन के समाप्त होने तक प्रतीक्षा करें

    fmt.Println(c.Value("somekey")) // आउटपुट: 1000

}

WaitGroup

sync.WaitGroup का उपयोग गोरूटीन के एक समूह के समाप्त होने तक प्रतीक्षा करने के लिए किया जाता है।

  • Add(delta int): वेटग्रुप के काउंटर को बढ़ाता है (कितने गोरूटीन की प्रतीक्षा करनी है)।
  • Done(): गोरूटीन समाप्त होने पर काउंटर को घटाता है (आमतौर पर defer के साथ प्रयोग किया जाता है)।
  • Wait(): ब्लॉक करता है जब तक कि काउंटर शून्य न हो जाए।

(ऊपर Mutex उदाहरण में WaitGroup का उपयोग दिखाया गया है।)

10. गो में एरर हैंडलिंग कैसे करें?

Go में एरर हैंडलिंग का एक विशिष्ट तरीका है जो अपवादों (exceptions) पर निर्भर नहीं करता है। इसके बजाय, फ़ंक्शन जो विफल हो सकते हैं, वे अपने अंतिम रिटर्न मान के रूप में एक error प्रकार का मान लौटाते हैं।

error एक अंतर्निहित इंटरफ़ेस प्रकार है:



type error interface {

    Error() string

}

सफल ऑपरेशन के लिए, एरर मान nil होता है। यदि कोई त्रुटि होती है, तो एरर मान गैर-nil होता है और इसमें त्रुटि का विवरण होता है। कॉलर का कर्तव्य है कि वह एरर मान की जाँच करे।



package main

import (

    "fmt"

    "strconv"

)

func main() {

    s := "123"

    // Atoi एक int और एक error लौटाता है

    n, err := strconv.Atoi(s) 

    if err != nil {

        // त्रुटि हुई, इसे संभालें

        fmt.Println("रूपांतरण में त्रुटि:", err)

        return // या कोई अन्य उपयुक्त कार्रवाई करें

    }

    // कोई त्रुटि नहीं, n का उपयोग करें

    fmt.Println("रूपांतरित संख्या:", n) // आउटपुट: रूपांतरित संख्या: 123

    s = "abc"

    n, err = strconv.Atoi(s)

    if err != nil {

        fmt.Println("रूपांतरण में त्रुटि:", err) // आउटपुट: रूपांतरण में त्रुटि: strconv.Atoi: parsing "abc": invalid syntax

        return

    }

    fmt.Println("रूपांतरित संख्या:", n) 

}

यह if err != nil पैटर्न Go कोड में बहुत आम है।

11. गो में एरर टाइप और एरर वैल्यू कैसे उपयोग करें?

आप विभिन्न तरीकों से एरर वैल्यू बना सकते हैं:

  • errors.New: एक साधारण, स्थिर एरर स्ट्रिंग के साथ एक एरर वैल्यू बनाने के लिए।
    
    
    import "errors"
    
    var ErrDivideByZero = errors.New("गणित: शून्य से विभाजन") 
    
    func divide(a, b int) (int, error) {
    
        if b == 0 {
    
            return 0, ErrDivideByZero // पूर्वनिर्धारित एरर लौटाएं
    
        }
    
        return a / b, nil
    
    }
    
            
  • fmt.Errorf: स्ट्रिंग फॉर्मेटिंग का उपयोग करके डायनामिक रूप से एरर संदेश बनाने के लिए।
    
    
    import "fmt"
    
    func readFile(filename string) error {
    
        // ... फ़ाइल खोलने का प्रयास करें ...
    
        if /* कोई समस्या हुई */ {
    
            return fmt.Errorf("फ़ाइल '%s' खोलने में विफल: %w", filename, underlyingError) // %w का उपयोग एरर रैपिंग के लिए होता है (Go 1.13+)
    
        }
    
        return nil
    
    }
    
            
  • कस्टम एरर टाइप्स (Custom Error Types): अधिक संरचनात्मक जानकारी प्रदान करने के लिए, आप अपने स्वयं के टाइप बना सकते हैं जो error इंटरफ़ेस को लागू करते हैं। यह कॉलर को एरर के बारे में अधिक जानने और उसके आधार पर निर्णय लेने की अनुमति देता है।
    
    
    package main
    
    import (
    
    	"fmt"
    
    	"time"
    
    )
    
    // कस्टम एरर टाइप
    
    type MyError struct {
    
    	When time.Time
    
    	What string
    
    }
    
    // error इंटरफ़ेस को लागू करें
    
    func (e *MyError) Error() string {
    
    	return fmt.Sprintf("%v पर: %s", e.When, e.What)
    
    }
    
    func run() error {
    
    	// कुछ ऑपरेशन करें जो विफल हो सकता है
    
    	return &MyError{
    
    		When: time.Now(),
    
    		What: "यह काम नहीं किया",
    
    	}
    
    }
    
    func main() {
    
    	if err := run(); err != nil {
    
    		fmt.Println(err) 
    
    		// टाइप असर्शन का उपयोग करके जांचें कि क्या यह हमारा कस्टम एरर है
    
    		if me, ok := err.(*MyError); ok {
    
    			fmt.Println("कस्टम एरर विवरण:")
    
    			fmt.Println("  समय:", me.When)
    
    			fmt.Println("  क्या हुआ:", me.What)
    
    		}
    
    	}
    
    }
    
            

12. गो में पैनिक और रिकवर कैसे उपयोग करें?

Go में panic और recover तंत्र हैं, लेकिन उनका उपयोग सामान्य एरर हैंडलिंग के लिए नहीं किया जाना चाहिए। error मान पसंदीदा तरीका है।

  • Panic:
    • panic फ़ंक्शन एक रनटाइम एरर शुरू करता है जो सामान्य नियंत्रण प्रवाह को रोकता है।
    • यह स्टैक को अनवाइंड करना शुरू कर देता है, प्रत्येक फ़ंक्शन कॉल से बाहर निकलते हुए और रास्ते में defer किए गए फ़ंक्शन को चलाता है।
    • यदि पैनिक पकड़ा नहीं जाता है (recover के साथ), तो प्रोग्राम क्रैश हो जाता है।
    • इसका उपयोग केवल वास्तव में असाधारण स्थितियों के लिए किया जाना चाहिए, जैसे कि एक असंभव स्थिति जो एक बग का संकेत देती है (उदाहरण के लिए, शून्य पॉइंटर डीरेफरेंस, आउट-ऑफ-बाउंड्स इंडेक्स)।
  • Recover:
    • recover एक अंतर्निहित फ़ंक्शन है जो पैनिकिंग गोरूटीन के नियंत्रण को पुनः प्राप्त करता है।
    • recover केवल defer किए गए फ़ंक्शन के अंदर उपयोगी है।
    • यदि वर्तमान गोरूटीन पैनिक कर रहा है, तो recover कॉल उस मान को कैप्चर करेगा जो panic को दिया गया था और सामान्य निष्पादन फिर से शुरू करेगा। यदि कोई पैनिक नहीं हो रहा है, तो recover nil लौटाता है।
    • आमतौर पर सर्वर अनुप्रयोगों में एक विशिष्ट हैंडलर को क्रैश होने से रोकने या पैनिक के दौरान संसाधनों को साफ करने के लिए उपयोग किया जाता है।


package main

import "fmt"

func mayPanic() {

    panic("एक समस्या!")

}

func main() {

    // पैनिक को पकड़ने के लिए defer फ़ंक्शन का उपयोग करें

    defer func() {

        // recover() केवल defer में काम करता है

        if r := recover(); r != nil {

            fmt.Println("रिकवर किया:", r) // पैनिक से मान प्राप्त करें

        }

    }() // तुरंत कॉल करें

    fmt.Println("mayPanic को कॉल करने से पहले।")

    mayPanic() // पैनिक यहीं होगा

    // यह लाइन कभी नहीं चलेगी क्योंकि पैनिक हो गया है

    fmt.Println("mayPanic को कॉल करने के बाद।") 

}

// आउटपुट:

// mayPanic को कॉल करने से पहले।

// रिकवर किया: एक समस्या!

सावधानी: panic/recover का अत्यधिक उपयोग कोड को समझना और बनाए रखना कठिन बना सकता है। हमेशा error मानों को प्राथमिकता दें।

13. गो में पैकेज और लाइब्रेरी कैसे उपयोग करें?

Go में कोड का पुन: उपयोग पैकेज और लाइब्रेरी के माध्यम से किया जाता है।

  • मानक लाइब्रेरी (Standard Library): Go के साथ आने वाले पैकेजों का एक समृद्ध सेट (fmt, net/http, os, io, sync, encoding/json आदि)। आप बस उन्हें import करके उपयोग कर सकते हैं।
  • थर्ड-पार्टी लाइब्रेरी (Third-Party Libraries): अन्य डेवलपर्स द्वारा बनाए गए पैकेज जो Go समुदाय द्वारा साझा किए जाते हैं (अक्सर GitHub जैसे प्लेटफॉर्म पर होस्ट किए जाते हैं)।

मानक लाइब्रेरी का उपयोग:



package main

import (

    "fmt"       // फॉर्मेटिंग और I/O

    "net/http" // HTTP क्लाइंट और सर्वर

    "os"        // ऑपरेटिंग सिस्टम फ़ंक्शन्स

)

func main() {

    fmt.Println("नमस्ते!") // fmt पैकेज

    resp, err := http.Get("https://www.google.com") // net/http पैकेज

    if err != nil {

        fmt.Fprintf(os.Stderr, "त्रुटि: %v\n", err) // os पैकेज (Stderr)

        os.Exit(1) // os पैकेज

    }

    defer resp.Body.Close() // सुनिश्चित करें कि बॉडी बंद हो

    fmt.Println("Google प्रतिक्रिया स्थिति:", resp.Status)

}

थर्ड-पार्टी लाइब्रेरी का उपयोग (Go Modules के साथ):

  1. मॉड्यूल इनिशियलाइज़ करें (यदि पहले से नहीं किया है): अपनी प्रोजेक्ट डायरेक्टरी के रूट में, चलाएँ:
    go mod init your_module_name
    (जैसे, go mod init mywebapp)। यह एक go.mod फ़ाइल बनाएगा।
  2. लाइब्रेरी प्राप्त करें: go get कमांड का उपयोग करें। उदाहरण के लिए, लोकप्रिय `gorilla/mux` राउटर प्राप्त करने के लिए:
    go get github.com/gorilla/mux
    यह लाइब्रेरी डाउनलोड करेगा और आपकी go.mod और go.sum फ़ाइलों को अपडेट करेगा।
  3. कोड में इम्पोर्ट और उपयोग करें:
    
    
    package main
    
    import (
    
        "fmt"
    
        "net/http"
    
        "github.com/gorilla/mux" // थर्ड-पार्टी पैकेज इम्पोर्ट करें
    
    )
    
    func HomeHandler(w http.ResponseWriter, r *http.Request) {
    
        fmt.Fprintln(w, "होम पेज!")
    
    }
    
    func main() {
    
        r := mux.NewRouter() // mux राउटर का उपयोग करें
    
        r.HandleFunc("/", HomeHandler)
    
        fmt.Println("सर्वर 8080 पर शुरू हो रहा है...")
    
        http.ListenAndServe(":8080", r)
    
    }
    
           

14. गो में कस्टम पैकेज कैसे बनाएं?

जैसा कि बिंदु 6 में दिखाया गया है, कस्टम पैकेज बनाना सीधा है:

  1. एक डायरेक्टरी बनाएं: अपने प्रोजेक्ट के अंदर पैकेज के लिए एक नई डायरेक्टरी बनाएं (जैसे, `utils`, `models`, `handlers`)।
  2. Go फ़ाइलें बनाएं: उस डायरेक्टरी के अंदर `.go` फ़ाइलें बनाएं।
  3. पैकेज घोषणा: प्रत्येक फ़ाइल की शुरुआत में `package <पैकेज_नाम>` घोषणा जोड़ें (जैसे, `package utils`)। डायरेक्टरी का नाम आमतौर पर पैकेज नाम के रूप में उपयोग किया जाता है।
  4. निर्यातित पहचानकर्ता (Exported Identifiers): यदि आप चाहते हैं कि फ़ंक्शन, टाइप या वेरिएबल पैकेज के बाहर से एक्सेस किए जा सकें, तो उनका नाम एक बड़े अक्षर से शुरू होना चाहिए।
  5. आयात करें: अपने `main` पैकेज या अन्य पैकेजों में, कस्टम पैकेज को उसके मॉड्यूल पथ के सापेक्ष पथ का उपयोग करके आयात करें (जैसे, `import "myproject/utils"` यदि आपका मॉड्यूल `myproject` है और पैकेज `utils` डायरेक्टरी में है)।

अपने प्रोजेक्ट को `go build` या `go run` के साथ बनाते समय, Go टूलिंग स्वचालित रूप से स्थानीय पैकेजों को ढूंढ और संकलित कर लेगी।

15. गो में थर्ड-पार्टी लाइब्रेरी कैसे उपयोग करें?

यह बिंदु 13 में विस्तार से बताया गया है। मुख्य चरण हैं:

  1. सुनिश्चित करें कि आपका प्रोजेक्ट एक Go मॉड्यूल है (go.mod फ़ाइल मौजूद है)। यदि नहीं, तो `go mod init <मॉड्यूल_पथ>` चलाएँ।
  2. वांछित लाइब्रेरी को डाउनलोड और इंस्टॉल करने के लिए `go get <लाइब्रेरी_पथ>` का उपयोग करें (जैसे, `go get github.com/spf13/cobra`)। यह निर्भरता को `go.mod` में जोड़ देगा।
  3. अपने Go कोड में `import` स्टेटमेंट का उपयोग करके लाइब्रेरी को आयात करें।
  4. लाइब्रेरी द्वारा प्रदान किए गए निर्यातित फ़ंक्शन, टाइप और वेरिएबल का उपयोग करें।

Go मॉड्यूल स्वचालित रूप से निर्भरता संस्करणों का प्रबंधन करते हैं, जिससे बिल्ड प्रतिलिपि प्रस्तुत करने योग्य (reproducible) बनते हैं।

16. गो में प्रदर्शन ऑप्टिमाइजेशन कैसे करें?

Go अपने आप में तेज़ है, लेकिन प्रदर्शन को और बेहतर बनाने के तरीके हैं:

  • सही एल्गोरिदम और डेटा संरचनाएं चुनें: यह अक्सर सबसे बड़ा प्रभाव डालता है।
  • अनावश्यक मेमोरी आवंटन से बचें:
    • बड़ी संरचनाओं को मान के बजाय पॉइंटर द्वारा पास करें (यदि उपयुक्त हो)।
    • स्लाइस और मैप्स बनाते समय `make` के साथ क्षमता (capacity) निर्दिष्ट करें यदि आकार ज्ञात है।
    • स्ट्रिंग संयोजन के लिए `+` के बजाय `strings.Builder` या `bytes.Buffer` का उपयोग करें (विशेषकर लूप में)।
    • मेमोरी को यथासंभव पुनः उपयोग करें।
  • बेंचमार्किंग और प्रोफाइलिंग का उपयोग करें (बिंदु 18 देखें): अनुमान न लगाएं! प्रदर्शन बाधाओं (bottlenecks) को खोजने के लिए Go के टूलिंग का उपयोग करें। go test -bench=. और pprof आपके मित्र हैं।
  • कनकरेंसी का बुद्धिमानी से उपयोग करें:
    • गोरूटीन हल्के होते हैं, लेकिन बहुत अधिक गोरूटीन बनाना और प्रबंधित करना ओवरहेड जोड़ सकता है।
    • रेस कंडीशन से बचने के लिए सिंक्रोनाइज़ेशन (चैनल या म्यूटेक्स) का सही उपयोग करें। अत्यधिक लॉकिंग प्रदर्शन को कम कर सकती है।
    • कार्यकर्ता पूल (worker pools) का उपयोग करके गोरूटीन की संख्या सीमित करें।
  • I/O ऑपरेशंस को बफर करें: फ़ाइलें या नेटवर्क कनेक्शन पढ़ते/लिखते समय `bufio` पैकेज का उपयोग करें।
  • मानक लाइब्रेरी का प्रभावी ढंग से उपयोग करें: मानक लाइब्रेरी के कई हिस्से अत्यधिक अनुकूलित हैं।
  • कंपाइलर ऑप्टिमाइजेशन को समझें: कभी-कभी कंपाइलर अनुकूलन (जैसे इनलाइनिंग) में मदद करने के लिए कोड को थोड़ा पुनर्व्यवस्थित करना सहायक हो सकता है, लेकिन यह उन्नत है।

17. गो में मेमोरी मैनेजमेंट कैसे करें?

Go में स्वचालित मेमोरी प्रबंधन होता है, जिसे गार्बेज कलेक्टर (GC) द्वारा नियंत्रित किया जाता है।

  • आवंटन (Allocation): जब आप `make()`, `new()` या कंपोजिट लिटरल (जैसे स्लाइस, मैप, स्ट्रक्ट) का उपयोग करके मान बनाते हैं, तो Go रनटाइम मेमोरी आवंटित करता है (या तो स्टैक पर या हीप पर)।
  • उपयोग (Usage): आप सामान्य रूप से वेरिएबल्स और पॉइंटर्स का उपयोग करते हैं।
  • गार्बेज कलेक्शन (Garbage Collection): GC समय-समय पर पृष्ठभूमि में चलता है। यह हीप पर आवंटित मेमोरी का पता लगाता है जिसका अब प्रोग्राम द्वारा सक्रिय रूप से उपयोग नहीं किया जा रहा है (यानी, उस तक कोई पहुंच योग्य पॉइंटर नहीं है) और उस मेमोरी को पुनः प्राप्त (reclaim) करता है ताकि इसे भविष्य के आवंटन के लिए पुन: उपयोग किया जा सके।

डेवलपर के लिए इसका क्या मतलब है:

  • आपको मैन्युअल रूप से मेमोरी `free` या `delete` करने की आवश्यकता नहीं है जैसा कि C/C++ में होता है।
  • आपको अभी भी मेमोरी लीक के बारे में पता होना चाहिए। एक लीक तब होता है जब मेमोरी आवंटित की जाती है लेकिन अब आवश्यक नहीं होने पर भी पहुंच योग्य बनी रहती है (उदाहरण के लिए, एक वैश्विक मैप में अनावश्यक संदर्भ रखना, या एक गोरूटीन जो चैनल पर हमेशा के लिए ब्लॉक हो गया है और संदर्भ रखता है)।
  • पॉइंटर्स का उपयोग मेमोरी पते को संदर्भित करने के लिए किया जाता है। & ऑपरेटर एक वेरिएबल का पता प्राप्त करता है, और * ऑपरेटर एक पॉइंटर को डीरेफरेंस करता है (उस पते पर मान तक पहुंचता है)। GC पॉइंटर्स को ट्रैक करता है।
  • GC के रुकने (pause times) को कम करने के लिए Go रनटाइम को अनुकूलित किया गया है, लेकिन अत्यधिक आवंटन दर अभी भी प्रदर्शन को प्रभावित कर सकती है। प्रदर्शन-संवेदनशील कोड में आवंटन को कम करना एक सामान्य अनुकूलन तकनीक है।

18. गो में प्रोफाइलिंग और बेंचमार्किंग कैसे करें?

Go प्रदर्शन विश्लेषण के लिए उत्कृष्ट अंतर्निहित उपकरण प्रदान करता है:

बेंचमार्किंग (Benchmarking)

यह विशिष्ट कोड खंडों के प्रदर्शन को मापने के लिए है।

  • बेंचमार्क फ़ंक्शन _test.go फ़ाइलों में लिखे जाते हैं।
  • उनका नाम Benchmark से शुरू होता है और *testing.B प्रकार का एक पैरामीटर लेता है।
  • कोड जिसे बेंचमार्क किया जाना है, वह for i := 0; i < b.N; i++ { ... } लूप के अंदर रखा जाता है। Go टूलिंग b.N के मान को समायोजित करेगा ताकि विश्वसनीय माप प्राप्त करने के लिए पर्याप्त समय तक चल सके।


// mypkg_test.go

package mypkg

import "testing"

func Fibonacci(n int) int {

	if n <= 1 {

		return n

	}

	return Fibonacci(n-1) + Fibonacci(n-2)

}

// बेंचमार्क फ़ंक्शन

func BenchmarkFibonacci10(b *testing.B) {

	// सेटअप यहाँ (यदि आवश्यक हो)

	for i := 0; i < b.N; i++ { // b.N बार चलाएं

		Fibonacci(10) // जिस फ़ंक्शन को बेंचमार्क करना है

	}

}

बेंचमार्क चलाने के लिए:

go test -bench=.

या केवल विशिष्ट बेंचमार्क चलाने के लिए:

go test -bench=Fibonacci

आउटपुट दिखाएगा कि ऑपरेशन में औसतन कितना समय लगा (ns/op) और कितनी मेमोरी आवंटित की गई (B/op)।

प्रोफाइलिंग (Profiling)

प्रोफाइलिंग आपको यह समझने में मदद करती है कि आपका प्रोग्राम अपना समय कहाँ बिता रहा है (CPU प्रोफाइलिंग) और मेमोरी कहाँ आवंटित की जा रही है (मेमोरी प्रोफाइलिंग)। Go का मुख्य प्रोफाइलिंग टूल pprof है।

  1. प्रोफाइल डेटा जेनरेट करें:
    • टेस्टिंग के माध्यम से: go test कमांड के साथ फ़्लैग का उपयोग करें:
      go test -cpuprofile cpu.prof -memprofile mem.prof -bench=.
      यह cpu.prof और mem.prof फ़ाइलें बनाएगा।
    • लाइव एप्लिकेशन से: net/http/pprof पैकेज आयात करें। यह आपके HTTP सर्वर पर /debug/pprof/ एंडपॉइंट जोड़ देगा।
      
      
      import _ "net/http/pprof" // साइड इफेक्ट्स के लिए इम्पोर्ट करें
      
      import "net/http"
      
      // ... अपना सर्वर सेटअप करें ...
      
      // http.ListenAndServe(":8080", nil) // या आपका राउटर
      
                      
      फिर आप ब्राउज़र या go tool pprof का उपयोग करके प्रोफाइल एक्सेस कर सकते हैं।
  2. प्रोफाइल डेटा का विश्लेषण करें: go tool pprof कमांड का उपयोग करें।
    go tool pprof cpu.prof
    या एक चल रहे सर्वर से कनेक्ट करने के लिए:
    go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30
    (30 सेकंड के लिए CPU प्रोफाइल एकत्र करता है)
    go tool pprof http://localhost:8080/debug/pprof/heap
    (वर्तमान मेमोरी हीप प्रोफाइल प्राप्त करता है) pprof टूल के अंदर, आप कमांड जैसे `top`, `list FunctionName`, `web` (ग्राफिकल व्यू उत्पन्न करता है, Graphviz इंस्टॉल होना चाहिए), `peek` आदि का उपयोग करके डेटा का विश्लेषण कर सकते हैं।

19. गो में वेब डेवलपमेंट कैसे करें?

Go वेब डेवलपमेंट के लिए एक लोकप्रिय विकल्प है, इसके प्रदर्शन, कनकरेंसी सुविधाओं और मजबूत मानक लाइब्रेरी (विशेष रूप से `net/http`) के कारण।

मुख्य क्षेत्र:

  • HTTP सर्वर बनाना: `net/http` पैकेज बुनियादी ढांचा प्रदान करता है।
  • राउटिंग (Routing): आने वाले अनुरोधों को सही हैंडलर फ़ंक्शन पर निर्देशित करना। मानक लाइब्रेरी सरल रूटिंग प्रदान करती है; अधिक उन्नत सुविधाओं के लिए, `gorilla/mux` या `chi` जैसे थर्ड-पार्टी राउटर का उपयोग किया जाता है।
  • रिक्वेस्ट हैंडलिंग: अनुरोध डेटा (हेडर, बॉडी, फॉर्म मान, URL पैरामीटर) को पढ़ना और संसाधित करना।
  • रिस्पांस लिखना: क्लाइंट को प्रतिक्रियाएं (HTML, JSON, आदि) भेजना।
  • टेम्पलेट्स: HTML प्रतिक्रियाओं को गतिशील रूप से उत्पन्न करने के लिए `html/template` या `text/template` पैकेज का उपयोग करना।
  • डेटाबेस इंटरैक्शन: `database/sql` पैकेज (SQL डेटाबेस के लिए) या विशिष्ट NoSQL डेटाबेस ड्राइवरों का उपयोग करना।
  • मिडलवेयर (Middleware): अनुरोध प्रसंस्करण पाइपलाइन में क्रॉस-कटिंग चिंताएं (जैसे लॉगिंग, प्रमाणीकरण, संपीड़न) जोड़ने के लिए।
  • JSON हैंडलिंग: वेब API के लिए `encoding/json` पैकेज।

20. गो में HTTP सर्वर और क्लाइंट कैसे उपयोग करें?

HTTP सर्वर

`net/http` पैकेज का उपयोग करके एक साधारण वेब सर्वर बनाना आसान है।



package main

import (

    "fmt"

    "net/http"

    "log"

)

// हैंडलर फ़ंक्शन

func helloHandler(w http.ResponseWriter, r *http.Request) {

    // r *http.Request से अनुरोध जानकारी पढ़ें (जैसे r.URL.Path)

	if r.URL.Path != "/hello" {

		http.NotFound(w, r)

		return

	}

    // w http.ResponseWriter का उपयोग करके प्रतिक्रिया लिखें

    fmt.Fprintf(w, "नमस्ते, वेब!") 

}

func main() {

    // रूट "/hello" को helloHandler फ़ंक्शन पर मैप करें

    http.HandleFunc("/hello", helloHandler) 

    // रूट "/" के लिए एक और हैंडलर

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		if r.URL.Path != "/" {

			http.NotFound(w, r)

			return

		}

        fmt.Fprintf(w, "मुख्य पृष्ठ!")

    })

    fmt.Println("सर्वर पोर्ट 8080 पर शुरू हो रहा है...")

    // सर्वर शुरू करें और सुनें

    // ListenAndServe ब्लॉक करता है जब तक कि कोई घातक त्रुटि न हो

    err := http.ListenAndServe(":8080", nil) // डिफ़ॉल्ट ServeMux का उपयोग करें

    if err != nil {

        log.Fatal("ListenAndServe त्रुटि: ", err)

    }

}

HTTP क्लाइंट

`net/http` पैकेज का उपयोग करके HTTP अनुरोध करना भी सरल है।



package main

import (

    "fmt"

    "net/http"

    "io/ioutil"

    "log"

)

func main() {

    // एक GET अनुरोध करें

    resp, err := http.Get("https://httpbin.org/get") // उदाहरण API एंडपॉइंट

    if err != nil {

        log.Fatalf("HTTP GET त्रुटि: %v", err)

    }

    // सुनिश्चित करें कि प्रतिक्रिया बॉडी बंद हो गई है

    defer resp.Body.Close()

    fmt.Println("प्रतिक्रिया स्थिति:", resp.Status)

    fmt.Println("प्रतिक्रिया हेडर:", resp.Header.Get("Content-Type"))

    // प्रतिक्रिया बॉडी पढ़ें

    body, err := ioutil.ReadAll(resp.Body)

    if err != nil {

        log.Fatalf("बॉडी पढ़ने में त्रुटि: %v", err)

    }

    fmt.Println("प्रतिक्रिया बॉडी:")

    fmt.Println(string(body))

    // POST, PUT, DELETE आदि जैसे अन्य तरीकों के लिए, http.NewRequest और http.DefaultClient.Do() का उपयोग करें।

}

21. गो में टेम्पलेट और डेटाबेस कैसे उपयोग करें?

टेम्पलेट्स (Templates)

Go के मानक लाइब्रेरी में दो मुख्य टेम्पलेट पैकेज हैं:

  • text/template: सामान्य टेक्स्ट आउटपुट उत्पन्न करने के लिए।
  • html/template: HTML आउटपुट उत्पन्न करने के लिए। यह स्वचालित रूप से डेटा को सुरक्षित करता है ताकि क्रॉस-साइट स्क्रिप्टिंग (XSS) हमलों को रोका जा सके, इसलिए वेब विकास के लिए इसे प्राथमिकता दी जाती है।

html/template का उदाहरण:

मान लें कि आपके पास `template.html` फ़ाइल है:



<!DOCTYPE html>

<html>

<head>

    <title>{{.Title}}</title>

</head>

<body>

    <h1>{{.Heading}}</h1>

    <p>{{.Message}}</p>

    <p>उपयोगकर्ता हैं:</p>

    <ul>

        {{range .Users}}

            <li>{{.}}</li>

        {{end}}

    </ul>

</body>

</html>

Go कोड:



package main

import (

    "html/template"

    "log"

    "net/http"

)

// डेटा संरचना जो टेम्पलेट को पास की जाएगी

type PageData struct {

    Title   string

    Heading string

    Message string

    Users   []string

}

func main() {

    // टेम्पलेट फ़ाइल को पार्स करें (आमतौर पर ऐप स्टार्टअप पर एक बार)

    tmpl, err := template.ParseFiles("template.html")

    if err != nil {

        log.Fatal("टेम्पलेट पार्स त्रुटि: ", err)

    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        // टेम्पलेट के लिए डेटा तैयार करें

        data := PageData{

            Title:   "मेरा पेज",

            Heading: "टेम्पलेट उदाहरण में आपका स्वागत है",

            Message: "यह Go के html/template पैकेज द्वारा प्रस्तुत किया गया है।",

            Users:   []string{"एलिस", "बॉब", "चार्ली"},

        }

        // टेम्पलेट को डेटा के साथ निष्पादित करें और परिणाम http.ResponseWriter में लिखें

        err := tmpl.Execute(w, data)

        if err != nil {

            log.Println("टेम्पलेट निष्पादन त्रुटि:", err)

            http.Error(w, "आंतरिक सर्वर त्रुटि", http.StatusInternalServerError)

        }

    })

    fmt.Println("सर्वर 8080 पर शुरू हो रहा है...")

    log.Fatal(http.ListenAndServe(":8080", nil))

}

डेटाबेस (Databases)

Go का database/sql पैकेज SQL (या SQL-जैसे) डेटाबेस के साथ इंटरैक्ट करने के लिए एक सामान्य इंटरफ़ेस प्रदान करता है। आपको विशिष्ट डेटाबेस के लिए एक ड्राइवर का उपयोग करने की आवश्यकता होगी।

  1. ड्राइवर प्राप्त करें: `go get` का उपयोग करें (उदाहरण के लिए, PostgreSQL के लिए `go get github.com/lib/pq` या MySQL के लिए `go get github.com/go-sql-driver/mysql`)।
  2. ड्राइवर आयात करें: आमतौर पर साइड इफेक्ट के लिए आयात किया जाता है (ताकि इसका `init` फ़ंक्शन चल सके और ड्राइवर को `database/sql` के साथ पंजीकृत कर सके)।
    import _ "github.com/lib/pq"
  3. डेटाबेस से कनेक्ट करें: `sql.Open("ड्राइवर-नाम", "कनेक्शन-स्ट्रिंग")` का उपयोग करें। यह तुरंत कनेक्शन स्थापित नहीं करता है, बल्कि एक `*sql.DB` ऑब्जेक्ट लौटाता है जो कनेक्शन पूल का प्रबंधन करता है।
  4. डेटाबेस को क्वेरी करें:
    • `db.QueryRow()`: एक पंक्ति वापस करने वाली क्वेरी के लिए (जैसे `SELECT ... WHERE id = ?`)।
    • `db.Query()`: कई पंक्तियाँ वापस करने वाली क्वेरी के लिए (जैसे `SELECT * FROM users`)।
    • `db.Exec()`: डेटा को संशोधित करने वाली क्वेरी के लिए (जैसे `INSERT`, `UPDATE`, `DELETE`), जो पंक्तियाँ वापस नहीं करती हैं।
  5. तैयार स्टेटमेंट (Prepared Statements): प्रदर्शन और सुरक्षा (SQL इंजेक्शन से बचाव) के लिए अक्सर उपयोग किए जाते हैं।

उदाहरण (PostgreSQL के साथ):



package main

import (

    "database/sql"

    "fmt"

    "log"

    _ "github.com/lib/pq" // PostgreSQL ड्राइवर आयात करें

)

type User struct {

    ID   int

    Name string

    Age  int

}

func main() {

    // कनेक्शन स्ट्रिंग (अपने क्रेडेंशियल्स से बदलें)

    connStr := "user=youruser password=yourpassword dbname=yourdb sslmode=disable"

    // डेटाबेस से कनेक्ट करें

    db, err := sql.Open("postgres", connStr)

    if err != nil {

        log.Fatal("डेटाबेस कनेक्शन त्रुटि:", err)

    }

    defer db.Close() // सुनिश्चित करें कि कनेक्शन पूल बंद हो गया है

    // कनेक्टिविटी जांचें

    err = db.Ping()

    if err != nil {

        log.Fatal("डेटाबेस पिंग त्रुटि:", err)

    }

    fmt.Println("डेटाबेस से सफलतापूर्वक कनेक्ट किया गया!")

    // एकल पंक्ति क्वेरी

    var user User

    userId := 1

    err = db.QueryRow("SELECT id, name, age FROM users WHERE id = $1", userId).Scan(&user.ID, &user.Name, &user.Age)

    if err != nil {

        if err == sql.ErrNoRows {

            fmt.Printf("आईडी %d वाला उपयोगकर्ता नहीं मिला\n", userId)

        } else {

            log.Fatal("QueryRow त्रुटि:", err)

        }

    } else {

        fmt.Printf("उपयोगकर्ता मिला: %+v\n", user)

    }

    // एकाधिक पंक्तियाँ क्वेरी

    rows, err := db.Query("SELECT id, name, age FROM users WHERE age > $1", 30)

    if err != nil {

        log.Fatal("Query त्रुटि:", err)

    }

    defer rows.Close() // सुनिश्चित करें कि पंक्तियाँ बंद हैं

    fmt.Println("30 से अधिक उम्र वाले उपयोगकर्ता:")

    for rows.Next() { // प्रत्येक पंक्ति के माध्यम से इटरेट करें

        var u User

        err := rows.Scan(&u.ID, &u.Name, &u.Age)

        if err != nil {

            log.Fatal("पंक्ति स्कैन त्रुटि:", err)

        }

        fmt.Printf(" - %+v\n", u)

    }

    // लूप के बाद त्रुटियों की जाँच करें

    if err = rows.Err(); err != nil {

        log.Fatal("पंक्ति पुनरावृत्ति त्रुटि:", err)

    }

	// डेटा डालने के लिए Exec का उपयोग करें

	newName := "डेविड"

	newAge := 25

	result, err := db.Exec("INSERT INTO users (name, age) VALUES ($1, $2)", newName, newAge)

	if err != nil {

		log.Fatal("Exec त्रुटि:", err)

	}

	rowsAffected, _ := result.RowsAffected()

	lastInsertId, _ := result.LastInsertId() // नोट: सभी ड्राइवर इसका समर्थन नहीं करते हैं

	fmt.Printf("उपयोगकर्ता डाला गया: प्रभावित पंक्तियाँ=%d, अंतिम आईडी=%v\n", rowsAffected, lastInsertId)

}

22. गो में सिस्टम प्रोग्रामिंग कैसे करें?

Go सिस्टम प्रोग्रामिंग कार्यों के लिए भी उपयुक्त है, जो पारंपरिक रूप से C, C++, या स्क्रिप्टिंग भाषाओं जैसे Python या Bash द्वारा किए जाते हैं। इसकी दक्षता, मजबूत मानक लाइब्रेरी और क्रॉस-कंपाइलेशन क्षमताएं इसे आकर्षक बनाती हैं।

सिस्टम प्रोग्रामिंग में शामिल हो सकते हैं:

  • फ़ाइल सिस्टम ऑपरेशंस: फ़ाइलें और डायरेक्टरी बनाना, पढ़ना, लिखना, हटाना, अनुमतियाँ प्रबंधित करना (os पैकेज)।
  • नेटवर्किंग: निम्न-स्तरीय TCP/UDP सॉकेट के साथ काम करना, नेटवर्क इंटरफेस को प्रबंधित करना (net पैकेज)।
  • प्रोसेस मैनेजमेंट: बाहरी कमांड और प्रक्रियाओं को चलाना और प्रबंधित करना (os/exec पैकेज)।
  • सिग्नल हैंडलिंग: ऑपरेटिंग सिस्टम सिग्नल (जैसे SIGINT, SIGTERM) को पकड़ना और प्रतिक्रिया देना (os/signal पैकेज)।
  • पर्यावरण चर और कमांड-लाइन तर्क: पढ़ना और उपयोग करना (os, flag पैकेज)।
  • सिस्टम कॉल: यदि आवश्यक हो तो निम्न-स्तरीय ऑपरेटिंग सिस्टम कॉल करना (syscall या golang.org/x/sys पैकेज - सावधानी से उपयोग करें)।

Go का स्टेटिक कंपाइलेशन एकल बाइनरी फ़ाइल बनाता है जिसमें कोई बाहरी रनटाइम निर्भरता नहीं होती है (डिफ़ॉल्ट रूप से), जिससे सिस्टम टूल और डेमॉन को तैनात करना आसान हो जाता है।

23. गो में फाइल सिस्टम और नेटवर्किंग कैसे उपयोग करें?

फाइल सिस्टम (os और io/ioutil पैकेज)

os पैकेज फ़ाइल सिस्टम के साथ इंटरैक्ट करने के लिए प्लेटफ़ॉर्म-स्वतंत्र इंटरफ़ेस प्रदान करता है। io/ioutil (अब io और os में एकीकृत) कुछ सुविधाजनक फ़ंक्शन प्रदान करता है।



package main

import (

    "fmt"

    "io/ioutil" // या Go 1.16+ में io और os

    "os"

    "log"

)

func main() {

    filename := "example.txt"

    data := []byte("यह फ़ाइल की सामग्री है।\nदूसरी पंक्ति।\n")

    // फ़ाइल में लिखें (सरल तरीका, पूरी फ़ाइल एक बार में)

    // Go 1.16+: err := os.WriteFile(filename, data, 0644)

    err := ioutil.WriteFile(filename, data, 0644) // 0644 अनुमतियाँ हैं

    if err != nil {

        log.Fatalf("फ़ाइल लिखने में त्रुटि: %v", err)

    }

    fmt.Printf("डेटा '%s' में सफलतापूर्वक लिखा गया\n", filename)

    // फ़ाइल पढ़ें (सरल तरीका, पूरी फ़ाइल एक बार में)

    // Go 1.16+: readData, err := os.ReadFile(filename)

    readData, err := ioutil.ReadFile(filename)

    if err != nil {

        log.Fatalf("फ़ाइल पढ़ने में त्रुटि: %v", err)

    }

    fmt.Printf("'%s' से पढ़ा गया डेटा:\n%s\n", filename, string(readData))

    // अधिक नियंत्रण के लिए os.OpenFile का उपयोग करें

    file, err := os.OpenFile("another.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)

    if err != nil {

        log.Fatalf("OpenFile त्रुटि: %v", err)

    }

    defer file.Close()

    _, err = file.WriteString("यह जोड़ा गया टेक्स्ट है।\n")

    if err != nil {

        log.Fatalf("WriteString त्रुटि: %v", err)

    }

    fmt.Println("टेक्स्ट 'another.txt' में जोड़ा गया")

    // फ़ाइल जानकारी प्राप्त करें

    fileInfo, err := os.Stat(filename)

    if err != nil {

        log.Fatalf("Stat त्रुटि: %v", err)

    }

    fmt.Printf("फ़ाइल जानकारी '%s': आकार=%d बाइट्स, मोड=%s\n", 

        fileInfo.Name(), fileInfo.Size(), fileInfo.Mode())

    // फ़ाइल हटाना

    // err = os.Remove(filename)

    // if err != nil {

    //     log.Fatalf("Remove त्रुटि: %v", err)

    // }

    // fmt.Printf("फ़ाइल '%s' हटाई गई\n", filename)

}

नेटवर्किंग (net पैकेज)

`net` पैकेज निम्न-स्तरीय नेटवर्किंग जैसे TCP/IP, UDP, डोमेन नाम रिज़ॉल्यूशन आदि के लिए है।

उदाहरण: एक साधारण TCP इको सर्वर



package main

import (

    "fmt"

    "net"

    "log"

    "io"

    "bufio"

)

func handleConnection(conn net.Conn) {

    fmt.Printf("स्वीकृत कनेक्शन %s से %s तक\n", conn.RemoteAddr(), conn.LocalAddr())

    defer conn.Close() // कनेक्शन बंद करना सुनिश्चित करें

	// सरल इको: जो कुछ भी पढ़ा जाता है उसे वापस लिखें

	// तरीका 1: io.Copy

	// _, err := io.Copy(conn, conn) 

    // if err != nil {

    //     log.Println("कॉपी त्रुटि:", err)

    // }

	// तरीका 2: लाइन दर लाइन पढ़ें और लिखें

	reader := bufio.NewReader(conn)

	for {

		line, err := reader.ReadString('\n')

		if err != nil {

			if err != io.EOF { // EOF एक अपेक्षित त्रुटि है जब क्लाइंट बंद हो जाता है

				log.Println("पढ़ने में त्रुटि:", err)

			}

			break // लूप से बाहर निकलें

		}

		fmt.Printf("प्राप्त: %s", line)

		// वापस लिखें

		_, err = conn.Write([]byte("आप ने कहा: " + line))

		if err != nil {

			log.Println("लिखने में त्रुटि:", err)

			break

		}

	}

	fmt.Printf("कनेक्शन बंद: %s\n", conn.RemoteAddr())

}

func main() {

    port := ":8081"

    // निर्दिष्ट पोर्ट पर TCP कनेक्शन सुनें

    listener, err := net.Listen("tcp", port)

    if err != nil {

        log.Fatalf("सुनने में त्रुटि: %v", err)

    }

    defer listener.Close() // सुनिश्चित करें कि श्रोता बंद है

    fmt.Printf("TCP इको सर्वर %s पर सुन रहा है...\n", port)

    for { // हमेशा के लिए कनेक्शन स्वीकार करें

        // आने वाले कनेक्शन की प्रतीक्षा करें और स्वीकार करें

        conn, err := listener.Accept()

        if err != nil {

            log.Printf("स्वीकार त्रुटि: %v\n", err)

            continue // अगले कनेक्शन पर जाएं

        }

        // प्रत्येक कनेक्शन को संभालने के लिए एक गोरूटीन शुरू करें

        go handleConnection(conn)

    }

}

आप `netcat` या `telnet` का उपयोग करके इस सर्वर से कनेक्ट कर सकते हैं: `nc localhost 8081`।

24. गो में प्रोसेस और सिग्नल हैंडलिंग कैसे करें?

प्रोसेस मैनेजमेंट (os/exec पैकेज)

`os/exec` पैकेज बाहरी कमांड चलाने की अनुमति देता है।



package main

import (

    "fmt"

    "os/exec"

    "log"

    "bytes"

)

func main() {

    // सरल कमांड चलाएं और आउटपुट प्राप्त करें

    cmd := exec.Command("ls", "-l", "/tmp") // कमांड और उसके तर्क

    

    // आउटपुट कैप्चर करने के लिए Run() के बजाय Output() का उपयोग करें

    out, err := cmd.Output() 

    if err != nil {

        log.Fatalf("कमांड चलाने में त्रुटि: %v", err)

    }

    fmt.Println("ls -l /tmp का आउटपुट:")

    fmt.Println(string(out))

    fmt.Println("\n------\n")

    // स्टडइन, स्टडआउट, स्टडरर को नियंत्रित करना

    cmd = exec.Command("grep", "hello")

    

    // कमांड के स्टडइन को पाइप करें

    cmd.Stdin = bytes.NewBufferString("goodbye\nhello world\nanother line\n")

    // कमांड के स्टडआउट और स्टडरर को कैप्चर करें

    var stdout, stderr bytes.Buffer

    cmd.Stdout = &stdout

    cmd.Stderr = &stderr

    // कमांड चलाएं (ब्लॉक करता है जब तक कि कमांड समाप्त न हो जाए)

    err = cmd.Run() 

    if err != nil {

        // grep को गैर-शून्य स्थिति के साथ बाहर निकलने पर भी त्रुटि नहीं मानी जानी चाहिए

		// यदि कुछ भी मेल नहीं खाता है, तो यह अपेक्षित है।

		// वास्तविक त्रुटियों के लिए stderr जांचें।

        log.Printf("कमांड समाप्त हुआ (संभावित गैर-शून्य निकास के साथ): %v\n", err)

    }

    fmt.Println("grep स्टडआउट:")

    fmt.Println(stdout.String()) // आउटपुट: hello world\n

    fmt.Println("grep स्टडरर:")

    fmt.Println(stderr.String()) // आमतौर पर खाली जब तक कि grep में कोई त्रुटि न हो

}

`Start()` और `Wait()` का उपयोग करके कमांड को एसिंक्रोनस रूप से भी चलाया जा सकता है।

सिग्नल हैंडलिंग (os/signal पैकेज)

आप अपने Go प्रोग्राम को ऑपरेटिंग सिस्टम सिग्नल (जैसे `SIGINT` जब Ctrl+C दबाया जाता है, या `SIGTERM` जब सिस्टम शटडाउन का अनुरोध करता है) को सुनने और प्रतिक्रिया देने के लिए सेट कर सकते हैं। यह ग्रेसफुल शटडाउन के लिए उपयोगी है।



package main

import (

	"fmt"

	"os"

	"os/signal"

	"syscall"

	"time"

)

func main() {

	// एक चैनल बनाएं जिस पर सिग्नल भेजे जाएंगे।

	// इसे बफर करना महत्वपूर्ण है, ताकि सिग्नल छूट न जाए

	// यदि प्रोग्राम तुरंत पढ़ने के लिए तैयार नहीं है।

	sigs := make(chan os.Signal, 1)

	// signal.Notify को बताएं कि हम कौन से सिग्नल पकड़ना चाहते हैं।

	// हम SIGINT (Ctrl+C) और SIGTERM (किल कमांड) पकड़ेंगे।

	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	// एक गोरूटीन शुरू करें जो सिग्नल की प्रतीक्षा करेगा।

	go func() {

		sig := <-sigs // सिग्नल आने तक ब्लॉक करें

		fmt.Println() // नई लाइन के लिए

		fmt.Println("सिग्नल प्राप्त हुआ:", sig)

		

		// यहाँ ग्रेसफुल शटडाउन लॉजिक करें

		// जैसे, खुले कनेक्शन बंद करें, डेटा सेव करें, आदि।

		fmt.Println("ग्रेसफुल शटडाउन शुरू...")

		time.Sleep(2 * time.Second) // शटडाउन का अनुकरण करें

		fmt.Println("शटडाउन पूर्ण।")

		// प्रोग्राम से बाहर निकलें

		os.Exit(0)

	}()

	fmt.Println("प्रोग्राम चल रहा है। बाहर निकलने के लिए Ctrl+C दबाएं।")

	

	// प्रोग्राम को चलते रहने दें (उदाहरण के लिए, एक सर्वर लूप)

	// यहाँ, हम बस हमेशा के लिए सोते हैं जब तक कि कोई सिग्नल इसे समाप्त न कर दे।

	select {} // हमेशा के लिए ब्लॉक करें

}

25. गो के अनुप्रयोग क्या हैं?

Go का उपयोग विभिन्न प्रकार के अनुप्रयोगों के निर्माण के लिए किया जाता है, जिनमें शामिल हैं:

  • क्लाउड-नेटिव एप्लिकेशन और नेटवर्क सेवाएं: माइक्रोसेवाएं, API बैकएंड, नेटवर्क प्रॉक्सी, लोड बैलेंसर। (जैसे Docker, Kubernetes, Istio, Cloudflare)।
  • कमांड-लाइन इंटरफेस (CLI) उपकरण: इसकी तेज स्टार्टअप गति और एकल बाइनरी परिनियोजन इसे CLI के लिए आदर्श बनाते हैं। (जैसे `kubectl`, `docker`, `terraform`, `hugo`)।
  • DevOps और साइट विश्वसनीयता इंजीनियरिंग (SRE) उपकरण: ऑटोमेशन स्क्रिप्ट, मॉनिटरिंग एजेंट, परिनियोजन उपकरण।
  • वेब डेवलपमेंट (बैकएंड): उच्च-प्रदर्शन वाले वेब सर्वर और API।
  • वितरित सिस्टम (Distributed Systems): कनकरेंसी मॉडल इसे वितरित कंप्यूटिंग कार्यों के लिए उपयुक्त बनाता है। (जैसे Consul, etcd)।
  • डेटाबेस और स्टोरेज सिस्टम: कुछ डेटाबेस (जैसे CockroachDB, TiDB) और स्टोरेज समाधान Go में लिखे गए हैं।
  • बिग डेटा प्रोसेसिंग: डेटा पाइपलाइन और प्रसंस्करण उपकरण।

यह उन क्षेत्रों में विशेष रूप से मजबूत है जहां प्रदर्शन, विश्वसनीयता और समवर्ती संचालन महत्वपूर्ण हैं।

26. गो का उपयोग विभिन्न उद्योगों में कैसे किया जाता है?

कई प्रमुख प्रौद्योगिकी कंपनियां और विभिन्न उद्योगों में संगठन Go का उपयोग कर रहे हैं:

  • Google: अपने कई आंतरिक सिस्टम, डाउनलोड सर्वर (`dl.google.com`), और प्रोजेक्ट जैसे Kubernetes के लिए।
  • Docker: कंटेनरीकरण प्लेटफ़ॉर्म बड़े पैमाने पर Go में लिखा गया है।
  • Kubernetes: कंटेनर ऑर्केस्ट्रेशन सिस्टम Go में लिखा गया है।
  • Cloudflare: अपने कई नेटवर्क एज सेवाओं, क्रिप्टोग्राफी और लॉग प्रोसेसिंग के लिए Go का उपयोग करता है।
  • Uber: उच्च-प्रदर्शन वाले माइक्रोसेवाओं और जियोफेंसिंग सेवाओं के लिए।
  • Twitch: अपने चैट सिस्टम सहित कई बैकएंड सेवाओं के लिए।
  • Dropbox: अपने कुछ महत्वपूर्ण बैकएंड इंफ्रास्ट्रक्चर के लिए।
  • SoundCloud: कई बैकएंड सेवाओं और माइक्रोसेवाओं के लिए।
  • HashiCorp: Terraform, Consul, Vault, Nomad जैसे लोकप्रिय DevOps टूल Go में लिखे गए हैं।
  • वित्तीय सेवाएँ (Financial Services): ट्रेडिंग सिस्टम, डेटा प्रोसेसिंग और API के लिए प्रदर्शन महत्वपूर्ण है।
  • ई-कॉमर्स (E-commerce): उच्च-ट्रैफिक बैकएंड सिस्टम और API के लिए।

Go की सादगी, प्रदर्शन और कनकरेंसी क्षमताएं इसे आधुनिक सॉफ्टवेयर विकास चुनौतियों के लिए कई उद्योगों में एक आकर्षक विकल्प बनाती हैं।

अतिरिक्त महत्वपूर्ण अवधारणाएं

इंटरफ़ेस (Interfaces)

इंटरफ़ेस Go में पॉलीमॉर्फिज्म और डीकपलिंग प्राप्त करने का एक शक्तिशाली तरीका है। एक इंटरफ़ेस प्रकार को मेथड सिग्नेचर के एक सेट के रूप में परिभाषित किया जाता है। कोई भी प्रकार जो उन सभी मेथड को लागू करता है, वह उस इंटरफ़ेस प्रकार को संतुष्ट करता है (बिना स्पष्ट घोषणा के - इसे डक टाइपिंग जैसा मानें)।



package main

import (

    "fmt"

    "math"

)

// Shape इंटरफ़ेस

type Shape interface {

    Area() float64 // सभी आकारों में Area() मेथड होना चाहिए

}

// Circle प्रकार

type Circle struct {

    Radius float64

}

// Circle के लिए Area मेथड (Shape इंटरफ़ेस को संतुष्ट करता है)

func (c Circle) Area() float64 {

    return math.Pi * c.Radius * c.Radius

}

// Rectangle प्रकार

type Rectangle struct {

    Width, Height float64

}

// Rectangle के लिए Area मेथड (Shape इंटरफ़ेस को संतुष्ट करता है)

func (r Rectangle) Area() float64 {

    return r.Width * r.Height

}

// एक फ़ंक्शन जो किसी भी Shape को स्वीकार करता है

func PrintArea(s Shape) {

    fmt.Printf("आकार का क्षेत्रफल: %0.2f\n", s.Area())

}

func main() {

    c := Circle{Radius: 5}

    r := Rectangle{Width: 4, Height: 6}

    PrintArea(c) // वृत्त पास करें

    PrintArea(r) // आयत पास करें

}

स्ट्रक्ट्स (Structs)

स्ट्रक्ट (संरचनाएं) विभिन्न प्रकार के नामित क्षेत्रों (fields) का एक संग्रह हैं। वे कस्टम डेटा प्रकार बनाने के लिए उपयोग किए जाते हैं।



package main

import "fmt"

// Person स्ट्रक्ट परिभाषा

type Person struct {

    FirstName string

    LastName  string

    Age       int

}

func main() {

    // स्ट्रक्ट बनाने के तरीके

    p1 := Person{FirstName: "एलिस", LastName: "स्मिथ", Age: 30}

    p2 := Person{"बॉब", "जॉनसन", 25} // क्रम महत्वपूर्ण है

    p3 := Person{FirstName: "चार्ली"} // छोड़े गए फ़ील्ड शून्य-मान वाले होंगे (Age=0)

    fmt.Println(p1)        // आउटपुट: {एलिस स्मिथ 30}

    fmt.Println(p2.LastName) // आउटपुट: जॉनसन

    fmt.Println(p3.Age)    // आउटपुट: 0

    // फ़ील्ड्स को संशोधित करना

    p1.Age = 31

    fmt.Println(p1.Age) // आउटपुट: 31

    // स्ट्रक्ट का पॉइंटर

    p4 := &Person{FirstName: "डेविड", Age: 40}

    fmt.Println(p4.FirstName) // Go स्वचालित रूप से पॉइंटर को डीरेफरेंस करता है (*p4).FirstName लिखने की जरूरत नहीं

}

पॉइंटर्स (Pointers)

एक पॉइंटर एक वेरिएबल होता है जो दूसरे वेरिएबल का मेमोरी एड्रेस स्टोर करता है।

  • & ऑपरेटर: एक वेरिएबल का मेमोरी एड्रेस देता है (एक पॉइंटर बनाता है)।
  • * ऑपरेटर:
    • एक प्रकार की घोषणा में (जैसे `*int`): यह एक पॉइंटर प्रकार को दर्शाता है।
    • एक पॉइंटर वेरिएबल के साथ: यह पॉइंटर को डीरेफरेंस करता है, यानी उस मेमोरी एड्रेस पर संग्रहीत मान तक पहुंचता है।

पॉइंटर्स का उपयोग अक्सर फ़ंक्शन को बड़े डेटा स्ट्रक्चर्स की कॉपी बनाने के बजाय उन्हें संशोधित करने की अनुमति देने के लिए या `nil` (शून्य पॉइंटर) मान इंगित करने के लिए किया जाता है कि कोई मान मौजूद नहीं है।



package main

import "fmt"

// यह फ़ंक्शन मान द्वारा int लेता है (कॉपी)

func zeroVal(ival int) {

    ival = 0 

}

// यह फ़ंक्शन एक int पॉइंटर लेता है

func zeroPtr(iptr *int) {

    *iptr = 0 // पॉइंटर को डीरेफरेंस करें और उस मेमोरी लोकेशन पर मान बदलें

}

func main() {

    i := 1

    fmt.Println("प्रारंभिक:", i) // आउटपुट: प्रारंभिक: 1

    zeroVal(i)

    fmt.Println("zeroVal के बाद:", i) // आउटपुट: zeroVal के बाद: 1 (i की कॉपी बदली गई थी)

    // &i i का मेमोरी एड्रेस देता है (एक *int पॉइंटर)

    zeroPtr(&i) 

    fmt.Println("zeroPtr के बाद:", i) // आउटपुट: zeroPtr के बाद: 0 (मूल i बदला गया था)

    // पॉइंटर का मान (मेमोरी एड्रेस) प्रिंट करें

    fmt.Println("पॉइंटर:", &i) 

}

कंट्रोल फ्लो (Control Flow)

Go मानक कंट्रोल फ्लो स्टेटमेंट प्रदान करता है:

  • if / else if / else: सशर्त निष्पादन।
    
    
    if num > 10 {
    
        fmt.Println("10 से बड़ा")
    
    } else if num < 10 {
    
        fmt.Println("10 से छोटा")
    
    } else {
    
        fmt.Println("10 के बराबर")
    
    }
    
    // स्टेटमेंट के साथ if (err := someFunc(); err != nil) भी आम है
    
            
  • for: Go का एकमात्र लूपिंग कंस्ट्रक्ट। इसका उपयोग विभिन्न तरीकों से किया जा सकता है:
    • C-स्टाइल फॉर लूप: `for i := 0; i < 10; i++ { ... }`
    • जबकि लूप: `for condition { ... }`
    • अनंत लूप: `for { ... }`
    • रेंज लूप (स्लाइस, मैप्स, स्ट्रिंग्स, चैनल पर इटरेट करने के लिए):
      
      
      nums := []int{1, 2, 3}
      
      for index, value := range nums {
      
          fmt.Println(index, value)
      
      }
      
      m := map[string]int{"a": 1, "b": 2}
      
      for key, value := range m {
      
          fmt.Println(key, value)
      
      }                
      
                      
  • switch: कई स्थितियों के विरुद्ध एक अभिव्यक्ति की तुलना करने का एक साफ तरीका। Go का `switch` C-परिवार की भाषाओं से अधिक लचीला है (जैसे, मामलों को स्थिर होने की आवश्यकता नहीं है, डिफ़ॉल्ट रूप से कोई फॉलथ्रू नहीं)।
    
    
    day := "सोमवार"
    
    switch day {
    
    case "शनिवार", "रविवार":
    
        fmt.Println("सप्ताहांत है")
    
    case "सोमवार":
    
        fmt.Println("सप्ताह की शुरुआत")
    
        // कोई break आवश्यक नहीं
    
    default:
    
        fmt.Println("कार्यदिवस है")
    
    }
    
    // बिना एक्सप्रेशन के स्विच (if/else if की तरह)
    
    score := 75
    
    switch {
    
    case score >= 90:
    
        fmt.Println("A")
    
    case score >= 80:
    
        fmt.Println("B")
    
    default:
    
        fmt.Println("C या नीचे")
    
    }
    
            
  • defer: एक फ़ंक्शन कॉल को तब तक के लिए स्थगित कर देता है जब तक कि आसपास का फ़ंक्शन वापस न आ जाए। डेफ़र किए गए कॉल LIFO (लास्ट-इन, फ़र्स्ट-आउट) क्रम में निष्पादित होते हैं। आमतौर पर संसाधनों को साफ करने के लिए उपयोग किया जाता है (जैसे फ़ाइलें बंद करना, म्यूटेक्स अनलॉक करना)।
  • break: सबसे भीतरी `for`, `switch`, या `select` स्टेटमेंट से बाहर निकलता है।
  • continue: सबसे भीतरी `for` लूप के अगले पुनरावृत्ति पर जाता है।
  • goto: लेबल वाले स्टेटमेंट पर बिना शर्त कूदता है (कम ही उपयोग किया जाता है)।

टिप्पणियाँ

इस ब्लॉग से लोकप्रिय पोस्ट

JavaScript basic to advance guide

Tool Room Lath Machine: A Complete Guide

html Post Creator introduction