Contents

Advanced Go Topics

Primitive Data Types

Reflection in Go allows you to inspect and manipulate the types and values of variables at runtime. It is provided by the reflect package and is useful for tasks like serializing objects, creating frameworks, and building tools that require introspection.

Basic Reflection Example

Here’s a simple example demonstrating how to use reflection to inspect a variable’s type and value:

				
					package main

import (
    "fmt"
    "reflect"
)

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

    fmt.Println("Type:", t)         // Output: Type: float64
    fmt.Println("Value:", v)        // Output: Value: 3.4
    fmt.Println("Kind:", v.Kind())  // Output: Kind: float64

    // Set value using reflection
    vPtr := reflect.ValueOf(&x) // Create a pointer to x
    vPtr.Elem().SetFloat(6.8)   // Set the value through the pointer
    fmt.Println("New Value:", x) // Output: New Value: 6.8
}

				
			

Key Concepts:

  • TypeOf: Returns the reflect.Type of a variable.
  • ValueOf: Returns the reflect.Value of a variable.
  • Kind: Returns the kind of type (e.g., Int, Float64).
  • Elem: Dereferences a pointer to access or modify the underlying value.
				
					float height = 5.9f;
				
			

Go Routines Deep Dive

Goroutines are lightweight threads managed by the Go runtime, enabling concurrent execution of functions. They are started using the go keyword and can communicate with each other using channels.

Basic Goroutine Example

Here’s an example of how to use goroutines for concurrent execution:

				
					package main

import (
    "fmt"
    "time"
)

func printNumbers() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    go printNumbers() // Start printNumbers as a goroutine
    fmt.Println("Goroutine started")

    // Wait for goroutine to finish (not ideal, just for demonstration)
    time.Sleep(600 * time.Millisecond)
    fmt.Println("Main function done")
}

				
			

Key Concepts:

  • Concurrency: Goroutines run concurrently with other goroutines.
  • Channels: Used for communication between goroutines, providing a way to synchronize execution and share data safely.

Using Channel

				
					package main

import (
    "fmt"
)

func sum(a []int, c chan int) {
    total := 0
    for _, v := range a {
        total += v
    }
    c <- total // Send the result to the channel
}

func main() {
    a := []int{1, 2, 3, 4, 5}
    c := make(chan int)

    go sum(a[:len(a)/2], c) // First half
    go sum(a[len(a)/2:], c) // Second half

    x, y := <-c, <-c // Receive from channel
    fmt.Println("Sum:", x+y)
}

				
			

Memory Management

Go features automatic memory management, mainly through its garbage collector, which helps manage memory allocation and deallocation. This means developers don’t have to manually manage memory, reducing the risk of memory leaks and errors.

Key Points on Memory Management

  • Garbage Collection: Automatically reclaims memory occupied by objects that are no longer in use.
  • Stack and Heap: Go uses stack allocation for local variables and heap allocation for dynamically allocated objects.
  • Escape Analysis: Determines whether variables should be allocated on the stack or heap based on their usage.

CGO

CGO allows Go programs to call C libraries, enabling the use of existing C code and libraries in Go applications. This can be useful for leveraging high-performance C libraries or accessing platform-specific features.

Basic CGO Example

To use CGO, you need to import the C pseudo-package and write C code within Go source files.

Example: Calling a C function from Go

				
					/*
#include <stdio.h>

void helloFromC() {
    printf("Hello from C!\n");
}
*/
import "C"

func main() {
    C.helloFromC() // Call the C function
}

				
			

Key Points:

  • Interoperability: CGO enables the use of C libraries and code in Go programs.
  • Performance: Useful for high-performance tasks where Go’s native capabilities may not suffice.
  • Platform-Specific Features: Access to platform-specific functionality provided by C libraries.