Skip to main content

Go Language Fundamentals

Lexical Elements

Keywords

  • Basic keywords (if, for, func, etc.)
  • Type-related keywords (type, struct, interface)
  • Package-related keywords (package, import)
  • Control flow keywords (return, break, continue)

Identifiers

  • Naming conventions
  • Exported vs unexported names
  • Package names
  • Variable naming best practices

Operators

  • Arithmetic operators
  • Comparison operators
  • Logical operators
  • Address and pointer operators
  • Channel operators

Data Types

  1. Basic Types

    • Integers (int8, int16, int32, int64)
    • Floating-point (float32, float64)
    • Complex numbers
    • Boolean
    • String
  2. Composite Types

    • Arrays
    • Slices
    • Maps
    • Structs
    • Pointers

Comments

  • Single-line comments
  • Multi-line comments
  • Package documentation
  • GoDoc conventions

Code Examples

Basic Types and Variables

package main

import "fmt"

func main() {
// Numeric types
var i int = 42
var f float64 = 3.14
complex := 1 + 2i

// String and rune
str := "Hello, 世界"
rune := '世'

// Arrays and slices
arr := [3]int{1, 2, 3}
slice := []int{1, 2, 3, 4}
slice = append(slice, 5)

// Maps
m := map[string]int{
"one": 1,
"two": 2,
}

fmt.Printf("Types: %T %T %T %T %T\n", i, f, complex, str, rune)
fmt.Printf("Slice: %v\n", slice)
fmt.Printf("Map: %v\n", m)
}

Composite Types

// Struct definition
type Person struct {
Name string
Age int
}

// Interface
type Speaker interface {
Speak() string
}

// Method implementation
func (p Person) Speak() string {
return fmt.Sprintf("My name is %s", p.Name)
}

// Function type
type MathFunc func(int, int) int

// Function using function type
func operate(a, b int, op MathFunc) int {
return op(a, b)
}

// Usage
func main() {
// Struct and interface usage
p := Person{Name: "Alice", Age: 30}
var s Speaker = p
fmt.Println(s.Speak())

// Function types
add := func(a, b int) int { return a + b }
result := operate(5, 3, add)
fmt.Printf("5 + 3 = %d\n", result)
}

Basic Syntax

  1. Package Declaration

    package main
  2. Import Statements

    import (
    "fmt"
    "strings"
    )
  3. Variable Declarations

    var name string
    age := 25

Control Structures

  1. Conditional Statements

    • if/else
    • switch/case
    • select (for channels)
  2. Loops

    • for loop variations
    • range iteration
    • break and continue

Functions

  1. Function Declaration

    func functionName(param1 type1, param2 type2) returnType {
    // function body
    }
  2. Multiple Return Values

    func divide(a, b float64) (float64, error) {
    if b == 0 {
    return 0, errors.New("division by zero")
    }
    return a / b, nil
    }
  3. Variadic Functions

    func sum(numbers ...int) int {
    total := 0
    for _, num := range numbers {
    total += num
    }
    return total
    }

Error Handling

  1. Error Type and Custom Errors

    // Standard error interface
    type error interface {
    Error() string
    }

    // Custom error type
    type ValidationError struct {
    Field string
    Message string
    }

    func (e *ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
    }
  2. Error Handling Patterns

    func processUser(name string, age int) (*User, error) {
    // Input validation
    if name == "" {
    return nil, &ValidationError{"name", "cannot be empty"}
    }
    if age < 0 {
    return nil, &ValidationError{"age", "must be positive"}
    }

    // Database operation simulation
    user, err := db.CreateUser(name, age)
    if err != nil {
    return nil, fmt.Errorf("failed to create user: %w", err)
    }

    return user, nil
    }

    // Error handling with type assertion
    func handleUser(name string, age int) {
    user, err := processUser(name, age)
    if err != nil {
    if ve, ok := err.(*ValidationError); ok {
    log.Printf("Validation error: %v", ve)
    return
    }
    log.Printf("Unexpected error: %v", err)
    return
    }
    fmt.Printf("Created user: %v\n", user)
    }

Concurrency Patterns

  1. Basic Goroutine and Channel Usage

    func main() {
    // Create a channel
    ch := make(chan string)

    // Start a goroutine
    go func() {
    ch <- "Hello from goroutine!"
    }()

    // Receive from channel
    msg := <-ch
    fmt.Println(msg)
    }
  2. Worker Pool Pattern

    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) // Simulate work
    results <- j * 2
    }
    }

    func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

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

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

    // Collect results
    for a := 1; a <= 5; a++ {
    <-results
    }
    }
  3. Select Statement

    func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
    time.Sleep(1 * time.Second)
    ch1 <- "one"
    }()

    go func() {
    time.Sleep(2 * time.Second)
    ch2 <- "two"
    }()

    // Using select to handle multiple channels
    for i := 0; i < 2; i++ {
    select {
    case msg1 := <-ch1:
    fmt.Println("Received", msg1)
    case msg2 := <-ch2:
    fmt.Println("Received", msg2)
    case <-time.After(3 * time.Second):
    fmt.Println("Timeout!")
    return
    }
    }
    }

Module System and Package Management

  1. Project Structure

    myproject/
    ├── go.mod
    ├── go.sum
    ├── main.go
    └── pkg/
    ├── models/
    │ └── user.go
    └── handlers/
    └── user_handler.go
  2. Module Setup

    # Initialize a new module
    go mod init example.com/myproject

    # Add dependencies
    go get github.com/pkg/errors
    go get golang.org/x/sync

    # Update dependencies
    go get -u ./...

    # Clean up unused dependencies
    go mod tidy
  3. Package Organization Example

    // pkg/models/user.go
    package models

    type User struct {
    ID int
    Name string
    Age int
    }

    // pkg/handlers/user_handler.go
    package handlers

    import (
    "example.com/myproject/pkg/models"
    "github.com/pkg/errors"
    )

    func CreateUser(name string, age int) (*models.User, error) {
    if name == "" {
    return nil, errors.New("name cannot be empty")
    }
    return &models.User{Name: name, Age: age}, nil
    }

    // main.go
    package main

    import (
    "fmt"
    "log"

    "example.com/myproject/pkg/handlers"
    )

    func main() {
    user, err := handlers.CreateUser("Alice", 30)
    if err != nil {
    log.Fatal(err)
    }
    fmt.Printf("Created user: %+v\n", user)
    }
  4. Module Configuration (go.mod)

    module example.com/myproject

    go 1.21

    require (
    github.com/pkg/errors v0.9.1
    golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
    )