Files
next.orly.dev/.claude/skills/golang/references/quick-reference.md
mleku fa71e9e334 Add Golang skill and reference materials
- Introduced a new skill for Golang, providing comprehensive guidance on writing, debugging, and best practices for Go programming.
- Added reference materials including effective Go guidelines, common patterns, and a quick reference cheat sheet to support users in Go development.
- Created a skill creator guide to assist in developing new skills with structured templates and resource management.
- Implemented scripts for skill initialization and packaging to streamline the skill creation process.
2025-11-04 12:36:36 +00:00

7.5 KiB

Go Quick Reference Cheat Sheet

Basic Syntax

Hello World

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Variables

var name string = "John"
var age int = 30
var height = 5.9  // type inference

// Short declaration (inside functions only)
count := 42

Constants

const Pi = 3.14159
const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
)

Data Types

Basic Types

bool                        // true, false
string                      // "hello"
int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64
byte                        // alias for uint8
rune                        // alias for int32 (Unicode)
float32 float64
complex64 complex128

Composite Types

// Array (fixed size)
var arr [5]int

// Slice (dynamic)
slice := []int{1, 2, 3}
slice = append(slice, 4)

// Map
m := make(map[string]int)
m["key"] = 42

// Struct
type Person struct {
    Name string
    Age  int
}
p := Person{Name: "Alice", Age: 30}

// Pointer
ptr := &p

Functions

// Basic function
func add(a, b int) int {
    return a + b
}

// Named returns (preferred)
func divide(a, b float64) (result float64, err error) {
    if b == 0 {
        err = errors.New("division by zero")
        return
    }
    result = a / b
    return
}

// Variadic
func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

// Multiple returns
func swap(a, b int) (int, int) {
    return b, a
}

Control Flow

If/Else

if x > 0 {
    // positive
} else if x < 0 {
    // negative
} else {
    // zero
}

// With initialization
if err := doSomething(); err != nil {
    return err
}

For Loops

// Traditional for
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// While-style
for condition {
}

// Infinite
for {
}

// Range
for i, v := range slice {
    fmt.Printf("%d: %v\n", i, v)
}

for key, value := range myMap {
    fmt.Printf("%s: %v\n", key, value)
}

Switch

switch x {
case 1:
    fmt.Println("one")
case 2, 3:
    fmt.Println("two or three")
default:
    fmt.Println("other")
}

// Type switch
switch v := i.(type) {
case int:
    fmt.Printf("int: %d\n", v)
case string:
    fmt.Printf("string: %s\n", v)
}

Methods & Interfaces

Methods

type Rectangle struct {
    Width, Height float64
}

// Value receiver
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

// Pointer receiver
func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}

Interfaces

type Shape interface {
    Area() float64
    Perimeter() float64
}

// Empty interface (any type)
var x interface{}  // or: var x any

Concurrency

Goroutines

go doSomething()

go func() {
    fmt.Println("In goroutine")
}()

Channels

// Create
ch := make(chan int)        // unbuffered
ch := make(chan int, 10)    // buffered

// Send & Receive
ch <- 42        // send
value := <-ch   // receive

// Close
close(ch)

// Check if closed
value, ok := <-ch

Select

select {
case msg := <-ch1:
    fmt.Println("ch1:", msg)
case msg := <-ch2:
    fmt.Println("ch2:", msg)
case <-time.After(1 * time.Second):
    fmt.Println("timeout")
default:
    fmt.Println("no channel ready")
}

Sync Package

// Mutex
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()

// RWMutex
var mu sync.RWMutex
mu.RLock()
defer mu.RUnlock()

// WaitGroup
var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    // work
}()
wg.Wait()

Error Handling

// Create errors
err := errors.New("error message")
err := fmt.Errorf("failed: %w", originalErr)

// Check errors
if err != nil {
    return err
}

// Custom error type
type MyError struct {
    Msg string
}

func (e *MyError) Error() string {
    return e.Msg
}

// Error checking (Go 1.13+)
if errors.Is(err, os.ErrNotExist) {
    // handle
}

var pathErr *os.PathError
if errors.As(err, &pathErr) {
    // handle
}

Standard Library Snippets

fmt - Formatting

fmt.Print("text")
fmt.Println("text with newline")
fmt.Printf("Name: %s, Age: %d\n", name, age)
s := fmt.Sprintf("formatted %v", value)

strings

strings.Contains(s, substr)
strings.HasPrefix(s, prefix)
strings.Join([]string{"a", "b"}, ",")
strings.Split(s, ",")
strings.ToLower(s)
strings.TrimSpace(s)

strconv

i, _ := strconv.Atoi("42")
s := strconv.Itoa(42)
f, _ := strconv.ParseFloat("3.14", 64)

io

io.Copy(dst, src)
data, _ := io.ReadAll(r)
io.WriteString(w, "data")

os

file, _ := os.Open("file.txt")
defer file.Close()
os.Getenv("PATH")
os.Exit(1)

net/http

// Server
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)

// Client
resp, _ := http.Get("https://example.com")
defer resp.Body.Close()

encoding/json

// Encode
data, _ := json.Marshal(obj)

// Decode
json.Unmarshal(data, &obj)

time

now := time.Now()
time.Sleep(5 * time.Second)
t.Format("2006-01-02 15:04:05")
time.Parse("2006-01-02", "2024-01-01")

Testing

Basic Test

// mycode_test.go
package mypackage

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    if result != 5 {
        t.Errorf("got %d, want 5", result)
    }
}

Table-Driven Test

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive", 2, 3, 5},
        {"negative", -1, -1, -2},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("got %d, want %d", result, tt.expected)
            }
        })
    }
}

Benchmark

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

Go Commands

# Run
go run main.go

# Build
go build
go build -o myapp

# Test
go test
go test -v
go test -cover
go test -race

# Format
go fmt ./...
gofmt -s -w .

# Lint
go vet ./...

# Modules
go mod init module-name
go mod tidy
go get package@version
go get -u ./...

# Install
go install

# Documentation
go doc package.Function

Common Patterns

Defer

file, err := os.Open("file.txt")
if err != nil {
    return err
}
defer file.Close()

Error Wrapping

if err != nil {
    return fmt.Errorf("failed to process: %w", err)
}

Context

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

Options Pattern

type Option func(*Config)

func WithPort(port int) Option {
    return func(c *Config) {
        c.port = port
    }
}

func New(opts ...Option) *Server {
    cfg := &Config{port: 8080}
    for _, opt := range opts {
        opt(cfg)
    }
    return &Server{cfg: cfg}
}

Format Verbs

%v   // default format
%+v  // struct with field names
%#v  // Go-syntax representation
%T   // type
%t   // bool
%d   // decimal integer
%b   // binary
%o   // octal
%x   // hex (lowercase)
%X   // hex (uppercase)
%f   // float
%e   // scientific notation
%s   // string
%q   // quoted string
%p   // pointer address
%w   // error wrapping

Best Practices

  1. Use gofmt to format code
  2. Always check errors
  3. Use named return values
  4. Prefer composition over inheritance
  5. Use defer for cleanup
  6. Keep functions small and focused
  7. Write table-driven tests
  8. Document exported names
  9. Use interfaces for flexibility
  10. Follow Effective Go guidelines