Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Go Best Practices

1. Code Formatting

Go places a strong emphasis on code formatting, which ensures readability and maintainability. Use the gofmt tool to format your code:

gofmt -w yourfile.go
                

2. Error Handling

Proper error handling is crucial in Go. Always check for errors and handle them appropriately. Here's an example:

package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    defer file.Close()
    // Process the file
}
                

3. Use of Goroutines

Goroutines are lightweight threads managed by the Go runtime. Use them for concurrent tasks:

package main

import (
    "fmt"
    "time"
)

func sayHello() {
    fmt.Println("Hello!")
}

func main() {
    go sayHello()
    time.Sleep(1 * time.Second)
}
                

4. Channel Communication

Channels provide a way for goroutines to communicate with each other and synchronize their execution:

package main

import "fmt"

func main() {
    messages := make(chan string)
    
    go func() { messages <- "ping" }()
    
    msg := <-messages
    fmt.Println(msg)
}
                

5. Package Management

Use Go modules for dependency management. Initialize a new module with:

go mod init your_module_name
                

6. Testing

Write tests for your Go code using the testing package. A simple test looks like this:

package main

import "testing"

func TestHello(t *testing.T) {
    got := Hello()
    want := "Hello, world!"
    if got != want {
        t.Errorf("got %q, want %q", got, want)
    }
}
                

7. Documentation

Document your code using comments and the GoDoc tool. Comments should be placed directly before the entities they describe:

package main

// Hello returns a greeting.
func Hello() string {
    return "Hello, world!"
}
                

8. Avoid Global Variables

Global variables can lead to unpredictable behavior and make testing difficult. Avoid them where possible:

package main

import "fmt"

func main() {
    var count int
    increment := func() {
        count++
    }
    increment()
    fmt.Println(count)
}
                

9. Use Context for Cancellation

Use the context package to handle cancellation and timeouts for goroutines:

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()
    
    select {
    case <-time.After(1 * time.Second):
        fmt.Println("operation completed")
    case <-ctx.Done():
        fmt.Println("operation timed out")
    }
}
                

10. Effective Logging

Use the log package for logging. It provides simple and efficient logging capabilities:

package main

import (
    "log"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        log.Fatalf("Failed to open file: %s", err)
    }
    defer file.Close()
    // Process the file
}