Go Lang Advance Concepts

Syed Muhammad Ali Raza - May 30 - - Dev Community

1. Concurrency Patterns

Worker Pools

Worker pools allow you to manage a large number of goroutines efficiently by limiting the number of active workers.

package main

import (
    "fmt"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Printf("Worker %d processing job %d\n", id, j)
        time.Sleep(time.Second)
        results <- j * 2
    }
}

func main() {
    const numJobs = 5
    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)

    // Start workers
    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    // Send jobs
    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs)

    // Collect results
    for a := 1; a <= numJobs; a++ {
        fmt.Println("Result:", <-results)
    }
}
Enter fullscreen mode Exit fullscreen mode

Select Statement

The select statement is used to wait on multiple channel operations.

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("Received", msg1)
        case msg2 := <-c2:
            fmt.Println("Received", msg2)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Reflection

Reflection in Go allows you to inspect the types of variables at runtime and manipulate objects with dynamic types.

Basic Reflection Example

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var x float64 = 3.4
    v := reflect.ValueOf(x)

    fmt.Println("Type:", v.Type())
    fmt.Println("Kind:", v.Kind())
    fmt.Println("Value:", v.Float())
}
Enter fullscreen mode Exit fullscreen mode

Modifying Values with Reflection

To modify a value using reflection, the value must be settable, which means it must be addressable.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var x float64 = 3.4
    p := reflect.ValueOf(&x)
    v := p.Elem()
    v.SetFloat(7.1)
    fmt.Println("Updated value:", x)
}
Enter fullscreen mode Exit fullscreen mode

3. Interfacing with C Libraries

Go can call C libraries using cgo, which is useful for integrating with existing C codebases or libraries.

Calling a Simple C Function

First, create a simple C library. For example, create a file named myclib.c:

// myclib.c
#include <stdio.h>

void myprint(const char* s) {
    printf("%s\n", s);
}
Enter fullscreen mode Exit fullscreen mode

Then create a Go program that uses this C function:

package main

/*
#include <stdio.h>
#include <stdlib.h>
void myprint(const char* s);
*/
import "C"
import "unsafe"

func main() {
    msg := C.CString("Hello from C!")
    C.myprint(msg)
    C.free(unsafe.Pointer(msg))
}
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .