Go Lang Advance Concepts

RMAG news

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 %dn, 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)
}
}

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)
}
}
}

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())
}

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)
}

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(“%sn, s);
}

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))
}