Toggle theme

Go Snippets

Common Go patterns and idioms

Error Handling

go

Idiomatic Go error handling patterns

// Basic error handling
func readFile(path string) ([]byte, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, fmt.Errorf("failed to open file: %w", err)
    }
    defer file.Close()
    
    data, err := io.ReadAll(file)
    if err != nil {
        return nil, fmt.Errorf("failed to read file: %w", err)
    }
    
    return data, nil
}

Goroutines & Channels

go

Concurrent programming in Go

func processItems(items []string) []string {
    results := make(chan string, len(items))
    var wg sync.WaitGroup

    for _, item := range items {
        wg.Add(1)
        go func(item string) {
            defer wg.Done()
            // Process item
            result := strings.ToUpper(item)
            results <- result
        }(item)
    }

    // Close results channel when all goroutines are done
    go func() {
        wg.Wait()
        close(results)
    }()

    // Collect results
    var processed []string
    for result := range results {
        processed = append(processed, result)
    }

    return processed
}

Interfaces

go

Interface definition and implementation

// Define interface
type Storage interface {
    Save(data []byte) error
    Load() ([]byte, error)
}

// Implement interface
type FileStorage struct {
    path string
}

func (fs *FileStorage) Save(data []byte) error {
    return os.WriteFile(fs.path, data, 0644)
}

func (fs *FileStorage) Load() ([]byte, error) {
    return os.ReadFile(fs.path)
}

// Use interface
func processData(storage Storage) error {
    data, err := storage.Load()
    if err != nil {
        return err
    }
    // Process data...
    return storage.Save(data)
}

Structs and Methods

go

Define custom types with methods

type User struct {
    ID        int
    Name      string
    Email     string
    CreatedAt time.Time
}

func (u *User) IsNew() bool {
    return time.Since(u.CreatedAt) < 24*time.Hour
}

func (u *User) Validate() error {
    if u.Name == "" {
        return errors.New("name is required")
    }
    if !strings.Contains(u.Email, "@") {
        return errors.New("invalid email")
    }
    return nil
}

// Usage
user := &User{
    Name:      "John",
    Email:     "john@example.com",
    CreatedAt: time.Now(),
}

if err := user.Validate(); err != nil {
    log.Fatal(err)
}