Some links in this article are affiliate links. We earn a commission at no extra cost to you when you purchase through them. Full disclosure.
Click any item to expand the explanation and examples. Coming from another language? Check out Go vs Python or our Rust cheat sheet.
📝 Basics
Variables and types basics
// Declare and assign var name string = "Alice" var age int = 30// Short declaration (most common) name := “Alice” age := 30 active := true
// Multiple x, y := 10, 20
// Constants const Pi = 3.14159 const ( StatusOK = 200 StatusError = 500 )
// Basic types // string, bool // int, int8, int16, int32, int64 // uint, uint8 (byte), uint16, uint32, uint64 // float32, float64 // complex64, complex128
// Zero values (defaults) // int → 0, float → 0.0, string → "", bool → false, pointer → nil
Functions basics
// Basic function
func greet(name string) string {
return "Hello, " + name
}
// Multiple return values
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf(“division by zero”)
}
return a / b, nil
}
result, err := divide(10, 3)
// Named return values
func swap(a, b int) (x, y int) {
x = b
y = a
return // naked return
}
// Variadic function
func sum(nums …int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
sum(1, 2, 3, 4)
// Anonymous function / closure
double := func(x int) int { return x * 2 }
double(5) // 10
📦 Data Structures
Slices data
// Create
nums := []int{1, 2, 3, 4, 5}
names := make([]string, 0, 10) // len=0, cap=10
// Append
nums = append(nums, 6)
nums = append(nums, 7, 8, 9)
// Slice
sub := nums[1:3] // [2, 3]
first3 := nums[:3] // [1, 2, 3]
last2 := nums[3:] // [4, 5]
// Length and capacity
len(nums)
cap(nums)
// Iterate
for i, v := range nums {
fmt.Println(i, v)
}
// Copy
dst := make([]int, len(nums))
copy(dst, nums)
// Delete element at index i
nums = append(nums[:i], nums[i+1:]…)
// Contains (no built-in — use slices package in Go 1.21+)
import “slices”
slices.Contains(nums, 3)
Maps data
// Create
ages := map[string]int{
"Alice": 30,
"Bob": 25,
}
// Or with make
ages := make(map[string]int)
// Set
ages[“Carol”] = 28
// Get (returns zero value if missing)
age := ages[“Alice”]
// Check if key exists
age, ok := ages[“Dave”]
if !ok {
fmt.Println(“Dave not found”)
}
// Delete
delete(ages, “Bob”)
// Iterate (order is random!)
for name, age := range ages {
fmt.Println(name, age)
}
// Length
len(ages)
Structs data
type User struct {
Name string
Email string
Age int
}
// Create
u := User{Name: “Alice”, Email: “alice@example.com”, Age: 30}
u := User{“Alice”, “alice@example.com”, 30} // positional
// Access
fmt.Println(u.Name)
u.Age = 31
// Pointer to struct
p := &User{Name: “Bob”}
p.Name = “Bob Updated” // Go auto-dereferences
// Methods
func (u User) FullName() string {
return u.Name
}
// Pointer receiver (can modify the struct)
func (u *User) SetEmail(email string) {
u.Email = email
}
// Embedding (composition)
type Admin struct {
User // Embedded — Admin “inherits” User fields
Level int
}
a := Admin{User: User{Name: “Alice”}, Level: 1}
a.Name // Works — promoted from User
🔌 Interfaces
Interfaces — implicit implementation interface
type Shape interface {
Area() float64
}
type Circle struct {
Radius float64
}
// Circle implements Shape (no “implements” keyword needed)
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Use the interface
func printArea(s Shape) {
fmt.Printf(“Area: %.2f\n”, s.Area())
}
printArea(Circle{Radius: 5})
printArea(Rectangle{Width: 3, Height: 4})
// Empty interface (accepts anything)
func printAnything(v any) { // any = interface{}
fmt.Println(v)
}
// Type assertion
var s Shape = Circle{Radius: 5}
c, ok := s.(Circle)
if ok {
fmt.Println(c.Radius)
}
⚠️ Error Handling
Errors in Go errors
import (
"errors"
"fmt"
)
// Return errors
func findUser(id int) (*User, error) {
if id <= 0 {
return nil, fmt.Errorf(“invalid id: %d”, id)
}
return &User{Name: “Alice”}, nil
}
// Handle errors (the Go way)
user, err := findUser(1)
if err != nil {
log.Fatal(err)
}
// Custom error types
type NotFoundError struct {
ID int
}
func (e *NotFoundError) Error() string {
return fmt.Sprintf(“user %d not found”, e.ID)
}
// Wrap errors (Go 1.13+)
return fmt.Errorf(“fetching user: %w”, err)
// Check wrapped errors
if errors.Is(err, ErrNotFound) { }
var nfe *NotFoundError
if errors.As(err, &nfe) {
fmt.Println(nfe.ID)
}
⚡ Goroutines & Channels
Concurrency concurrency
// Start a goroutine go doWork()// Channel — communicate between goroutines ch := make(chan string)
go func() { ch <- “hello” // Send }()
msg := <-ch // Receive (blocks until value available)
// Buffered channel ch := make(chan int, 5) // Buffer size 5
// Range over channel go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) }()
for v := range ch { fmt.Println(v) }
// Select — wait on multiple channels select { case msg := <-ch1: fmt.Println(msg) case msg := <-ch2: fmt.Println(msg) case <-time.After(5 * time.Second): fmt.Println(“timeout”) }
// WaitGroup — wait for goroutines to finish var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() fmt.Println(“Worker”, id) }(i) } wg.Wait()
🔧 Common Operations
Strings, JSON, HTTP stdlib
// Strings
import "strings"
strings.Contains("hello", "ell") // true
strings.HasPrefix("hello", "he") // true
strings.Split("a,b,c", ",") // ["a","b","c"]
strings.Join([]string{"a","b"}, "-") // "a-b"
strings.ToUpper("hello") // "HELLO"
strings.TrimSpace(" hi ") // "hi"
fmt.Sprintf("Hello %s, age %d", name, age)
// JSON
import “encoding/json”
// Struct to JSON
data, _ := json.Marshal(user)
// JSON to struct
json.Unmarshal(data, &user)
// HTTP server
http.HandleFunc(”/”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, “Hello!”)
})
http.ListenAndServe(“:8080”, nil)
// HTTP client
resp, err := http.Get(“https://api.example.com/users”)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
CLI commands cli
# Initialize module go mod init github.com/user/projectAdd dependencies
go get github.com/gin-gonic/gin
Tidy (remove unused, add missing)
go mod tidy
Run
go run main.go go run .
Build
go build -o myapp .
Test
go test ./… go test -v ./… go test -cover ./…
Format
go fmt ./…
Vet (find bugs)
go vet ./…
Quick access: Raycast lets you search commands, snippets, and cheat sheets instantly from your keyboard. Free for Mac.
Related: go nil pointer dereference fix · go context deadline exceeded fix · rust vs go