Golang Cheatsheet

Изучите Golang с практическими лабораториями

Изучите программирование на Go с помощью практических лабораторий и сценариев из реального мира. LabEx предлагает комплексные курсы по Go, охватывающие основной синтаксис, шаблоны параллелизма, обработку ошибок и продвинутые методы. Освойте уникальные возможности Go, такие как goroutines, каналы и интерфейсы, для создания эффективных, параллельных приложений.

Installation & Setup

Install Go: Download & Extract

Скачайте и установите Go с официального сайта.

# Download from https://golang.org/dl/
# Linux/macOS - extract to /usr/local
sudo tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz
# Add to PATH in ~/.bashrc or ~/.zshrc
export PATH=$PATH:/usr/local/go/bin
# Verify installation
go version

Package Manager: Using Homebrew (macOS)

Установите Go с помощью Homebrew на macOS.

# Install Go with Homebrew
brew install go
# Verify installation
go version
go env GOPATH

Windows Installation

Установка Go в системах Windows.

# Download .msi installer from https://golang.org/dl/
# Run installer and follow prompts
# Verify in Command Prompt
go version
echo %GOPATH%

Workspace Setup: go mod init

Инициализация нового модуля и рабочей области Go.

# Create new directory and initialize module
mkdir my-go-project
cd my-go-project
go mod init my-go-project
# Create main.go
echo 'package main
import "fmt"
func main() {
    fmt.Println("Hello, World!")
}' > main.go
# Run the program
go run main.go

Environment Variables

Важные переменные окружения Go.

# View all Go environment variables
go env
# Key variables
go env GOROOT    # Go installation directory
go env GOPATH    # Workspace directory
go env GOOS      # Operating system
go env GOARCH    # Architecture

IDE Setup: VS Code

Настройка VS Code для разработки на Go.

# Install Go extension in VS Code
# Ctrl+Shift+P -> Go: Install/Update Tools
# Key features enabled:
# - Syntax highlighting
# - IntelliSense
# - Debugging
# - Testing integration

Basic Syntax & Types

Package & Imports

Каждый файл Go начинается с объявления пакета и импортов.

package main
import (
    "fmt"
    "strings"
    "time"
)
// Single import
import "os"

Variables & Constants

Объявление и инициализация переменных и констант.

// Variable declarations
var name string = "Go"
var age int = 15
var isOpen bool
// Short declaration
name := "Golang"
count := 42
// Constants
const Pi = 3.14159
const Message = "Hello, Go!"
Викторина

Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения

What is the difference between var name string = "Go" and name := "Go"?
There is no difference
:= is short declaration that infers the type, var explicitly declares the type
:= can only be used for constants
var can only be used inside functions

Basic Data Types

Основные типы данных, доступные в Go.

// Numeric types
var i int = 42
var f float64 = 3.14
var c complex64 = 1 + 2i
// Text types
var s string = "Hello"
var r rune = 'A'
// Boolean
var b bool = true

Control Flow

Conditionals: if / else / switch

Управление потоком программы с помощью условных операторов.

// If statements
if age >= 18 {
    fmt.Println("Adult")
} else if age >= 13 {
    fmt.Println("Teenager")
} else {
    fmt.Println("Child")
}
// Switch statements
switch day {
case "Monday":
    fmt.Println("Start of work week")
case "Friday":
    fmt.Println("TGIF")
default:
    fmt.Println("Regular day")
}

Loops: for / range

Итерация с использованием различных конструкций цикла.

// Traditional for loop
for i := 0; i < 10; i++ {
    fmt.Println(i)
}
// While-style loop
for condition {
    // loop body
}
// Infinite loop
for {
    // break when needed
}

Range Iteration

Итерация по срезам (slices), массивам (arrays), картам (maps) и строкам (strings).

// Iterate over slice
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
    fmt.Printf("Index: %d, Value: %d\n", index, value)
}
// Iterate over map
colors := map[string]string{"red": "#FF0000", "green": "#00FF00"}
for key, value := range colors {
    fmt.Printf("%s: %s\n", key, value)
}
// Iterate over string
for i, char := range "Hello" {
    fmt.Printf("%d: %c\n", i, char)
}
Викторина

Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения

What does range return when iterating over a slice in Go?
Only the value
Both the index and the value
Only the index
The length of the slice

Control Statements: break / continue

Управление потоком выполнения цикла.

// Break out of loop
for i := 0; i < 10; i++ {
    if i == 5 {
        break
    }
    fmt.Println(i)
}
// Skip current iteration
for i := 0; i < 5; i++ {
    if i == 2 {
        continue
    }
    fmt.Println(i)
}
Викторина

Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения

What is the difference between break and continue in Go loops?
There is no difference
break skips the current iteration, continue exits the loop
break exits the loop completely, continue skips to the next iteration
Both exit the loop

Functions

Function Declaration: func

Определение функций с параметрами и возвращаемыми значениями.

// Basic function
func greet(name string) {
    fmt.Printf("Hello, %s!\n", name)
}
// Function with return value
func add(a, b int) int {
    return a + b
}
// Multiple return values
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

Named Returns & Variadic Functions

Расширенные возможности функций и шаблоны.

// Named return values
func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return // naked return
}
// Variadic function
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}
// Usage
result := sum(1, 2, 3, 4, 5)

Function Types & Closures

Функции как первоклассные объекты в Go.

// Function as variable
var multiply func(int, int) int
multiply = func(a, b int) int {
    return a * b
}
// Anonymous function
square := func(x int) int {
    return x * x
}
// Closure
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}
// Usage
c := counter()
fmt.Println(c()) // 1
fmt.Println(c()) // 2

Defer Statement

Отложить выполнение функций до возврата окружающей функции.

func processFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close() // Executed when function returns

    // Process file contents
    // file.Close() will be called automatically
}

Data Structures

Arrays & Slices

Фиксированные и динамические последовательности элементов.

// Arrays (fixed size)
var arr [5]int = [5]int{1, 2, 3, 4, 5}
shortArr := [3]string{"a", "b", "c"}
// Slices (dynamic)
var slice []int
slice = append(slice, 1, 2, 3)
// Make slice with capacity
numbers := make([]int, 5, 10) // length 5, capacity 10
// Slice operations
slice2 := slice[1:3]  // [2, 3]
copy(slice2, slice)   // Copy elements

Maps

Пары ключ-значение для эффективного поиска.

// Map declaration and initialization
var m map[string]int
m = make(map[string]int)
// Short declaration
ages := map[string]int{
    "Alice": 30,
    "Bob":   25,
    "Carol": 35,
}
// Map operations
ages["David"] = 40        // Add/update
delete(ages, "Bob")       // Delete
age, exists := ages["Alice"] // Check existence

Structs

Группировка связанных данных с пользовательскими типами.

// Struct definition
type Person struct {
    Name    string
    Age     int
    Email   string
}
// Create struct instances
p1 := Person{
    Name:  "Alice",
    Age:   30,
    Email: "alice@example.com",
}
p2 := Person{"Bob", 25, "bob@example.com"}
// Access fields
fmt.Println(p1.Name)
p1.Age = 31

Pointers

Ссылки на адреса памяти переменных.

// Pointer declaration
var p *int
num := 42
p = &num  // Address of num
// Dereferencing
fmt.Println(*p) // Value at address (42)
*p = 100        // Change value through pointer
// Pointers with structs
person := &Person{Name: "Alice", Age: 30}
person.Age = 31  // Automatic dereferencing

Methods & Interfaces

Methods

Привязка функциональности к пользовательским типам.

type Rectangle struct {
    Width, Height float64
}
// Method with receiver
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}
// Pointer receiver (can modify)
func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}
// Usage
rect := Rectangle{Width: 10, Height: 5}
fmt.Println(rect.Area()) // 50
rect.Scale(2)            // Modifies rect

Interfaces

Определение контрактов, которым должны соответствовать типы.

// Interface definition
type Shape interface {
    Area() float64
    Perimeter() float64
}
// Implement interface for Rectangle
func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Height)
}
// Rectangle now implements Shape interface
func printShapeInfo(s Shape) {
    fmt.Printf("Area: %.2f, Perimeter: %.2f\n",
               s.Area(), s.Perimeter())
}

Empty Interface & Type Assertions

Работа со значениями неизвестных типов.

// Empty interface can hold any value
var i interface{}
i = 42
i = "hello"
i = []int{1, 2, 3}
// Type assertion
str, ok := i.(string)
if ok {
    fmt.Printf("String value: %s\n", str)
}
// Type switch
switch v := i.(type) {
case int:
    fmt.Printf("Integer: %d\n", v)
case string:
    fmt.Printf("String: %s\n", v)
default:
    fmt.Printf("Unknown type: %T\n", v)
}

Embedding

Компоновка типов путем встраивания других типов.

type Person struct {
    Name string
    Age  int
}
type Employee struct {
    Person    // Embedded struct
    Company   string
    Salary    float64
}
// Usage
emp := Employee{
    Person:  Person{Name: "Alice", Age: 30},
    Company: "TechCorp",
    Salary:  75000,
}
// Access embedded fields directly
fmt.Println(emp.Name) // "Alice"

Error Handling

Basic Error Handling

Использование встроенного интерфейса error для обработки ошибок.

import "errors"
// Function that returns an error
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}
// Error checking
result, err := divide(10, 2)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Result: %.2f\n", result)

Custom Errors

Создание пользовательских типов ошибок для специфических условий.

// Custom error type
type ValidationError struct {
    Field   string
    Message string
}
func (e ValidationError) Error() string {
    return fmt.Sprintf("validation error in %s: %s",
                       e.Field, e.Message)
}
// Function using custom error
func validateAge(age int) error {
    if age < 0 {
        return ValidationError{
            Field:   "age",
            Message: "must be non-negative",
        }
    }
    return nil
}

Error Wrapping

Добавление контекста к ошибкам с сохранением исходной ошибки.

import "fmt"
// Wrap an error with additional context
func processFile(filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return fmt.Errorf("failed to open file %s: %w",
                          filename, err)
    }
    defer file.Close()

    // Process file...
    return nil
}
// Unwrap errors
err := processFile("missing.txt")
if err != nil {
    var pathErr *os.PathError
    if errors.As(err, &pathErr) {
        fmt.Println("Path error:", pathErr)
    }
}

Panic & Recovery

Обработка исключительных ситуаций с помощью panic и recover.

// Function that might panic
func riskyOperation() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()

    // This will cause a panic
    panic("something went wrong!")
}
// Usage
riskyOperation() // Program continues after panic

Concurrency

Goroutines

Легковесные потоки, управляемые средой выполнения Go.

import "time"
// Simple goroutine
func sayHello() {
    fmt.Println("Hello from goroutine!")
}
func main() {
    // Start goroutine
    go sayHello()

    // Anonymous goroutine
    go func() {
        fmt.Println("Anonymous goroutine")
    }()

    // Wait for goroutines to finish
    time.Sleep(time.Second)
}

Channels

Обмен данными между горутинами с использованием каналов.

// Create channel
ch := make(chan int)
// Buffered channel
buffered := make(chan string, 3)
// Send and receive
go func() {
    ch <- 42  // Send value
}()
value := <-ch  // Receive value
// Close channel
close(ch)

Channel Patterns

Общие шаблоны для коммуникации по каналам.

// Worker pattern
func worker(id int, jobs <-chan int, results chan<- int) {
    for job := range jobs {
        fmt.Printf("Worker %d processing job %d\n", id, job)
        results <- job * 2
    }
}
// Fan-out pattern
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)

Select Statement

Обработка нескольких операций с каналами одновременно.

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

    go func() {
        time.Sleep(time.Second)
        ch1 <- "from ch1"
    }()

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

    // Select first available channel
    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    case <-time.After(3 * time.Second):
        fmt.Println("timeout")
    }
}

File I/O & JSON

File Operations

Чтение и запись файлов с использованием различных методов.

import (
    "io/ioutil"
    "os"
)
// Read entire file
data, err := ioutil.ReadFile("file.txt")
if err != nil {
    log.Fatal(err)
}
content := string(data)
// Write to file
text := "Hello, World!"
err = ioutil.WriteFile("output.txt", []byte(text), 0644)
// Open file with more control
file, err := os.Open("data.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

CSV Handling

Чтение и запись CSV-файлов.

import (
    "encoding/csv"
    "os"
)
// Read CSV
file, _ := os.Open("data.csv")
defer file.Close()
reader := csv.NewReader(file)
records, _ := reader.ReadAll()
// Write CSV
file, _ = os.Create("output.csv")
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
writer.Write([]string{"Name", "Age", "City"})
writer.Write([]string{"Alice", "30", "NYC"})

JSON Processing

Кодирование и декодирование JSON-данных.

import "encoding/json"
// Struct for JSON mapping
type Person struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Email string `json:"email,omitempty"`
}
// Marshal (Go to JSON)
person := Person{Name: "Alice", Age: 30}
jsonData, err := json.Marshal(person)
if err != nil {
    log.Fatal(err)
}
// Unmarshal (JSON to Go)
var p Person
err = json.Unmarshal(jsonData, &p)

HTTP Requests

Выполнение HTTP-запросов и обработка ответов.

import "net/http"
// GET request
resp, err := http.Get("https://api.github.com/users/octocat")
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
// POST request with JSON
jsonData := []byte(`{"name":"Alice","age":30}`)
resp, err = http.Post("https://api.example.com/users",
                      "application/json",
                      bytes.NewBuffer(jsonData))

Testing

Unit Testing: go test

Написание и запуск тестов с использованием фреймворка тестирования Go.

// math.go
package main
func Add(a, b int) int {
    return a + b
}
// math_test.go
package main
import "testing"
func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5

    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}
// Run tests
// go test
// go test -v (verbose)

Table-Driven Tests

Эффективное тестирование нескольких случаев.

func TestAddMultiple(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"with zero", 0, 5, 5},
        {"negative numbers", -1, -2, -3},
    }

    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)
            }
        })
    }
}

Benchmarking

Измерение производительности функций.

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}
// Run benchmarks
// go test -bench=.
// go test -bench=BenchmarkAdd -benchmem

Example Tests

Создание исполняемых примеров, служащих документацией.

import "fmt"
func ExampleAdd() {
    result := Add(2, 3)
    fmt.Printf("2 + 3 = %d", result)
    // Output: 2 + 3 = 5
}
func ExampleAdd_negative() {
    result := Add(-1, -2)
    fmt.Printf("(-1) + (-2) = %d", result)
    // Output: (-1) + (-2) = -3
}
// Run examples
// go test -run Example

Go Modules & Packages

Module Management

Инициализация и управление модулями Go для управления зависимостями.

# Initialize new module
go mod init github.com/username/project
# Add dependencies
go get github.com/gorilla/mux
go get -u github.com/gin-gonic/gin  # Update to latest
# Remove unused dependencies
go mod tidy
# Download dependencies
go mod download
# Vendor dependencies locally
go mod vendor

go.mod File

Понимание файла определения модуля.

module github.com/username/myproject
go 1.21
require (
    github.com/gorilla/mux v1.8.0
    github.com/stretchr/testify v1.8.4
)
require (
    github.com/davecgh/go-spew v1.1.1 // indirect
    github.com/pmezard/go-difflib v1.0.0 // indirect
)

Creating Packages

Структурирование кода в многократно используемые пакеты.

// Package structure
// myproject/
//   ├── go.mod
//   ├── main.go
//   └── utils/
//       ├── math.go
//       └── string.go
// utils/math.go
package utils
// Exported function (starts with capital letter)
func Add(a, b int) int {
    return a + b
}
// Private function (starts with lowercase)
func multiply(a, b int) int {
    return a * b
}
// main.go
package main
import (
    "fmt"
    "github.com/username/myproject/utils"
)
func main() {
    result := utils.Add(5, 3)
    fmt.Println(result)
}

Common Go Commands

Основные команды для разработки на Go.

# Run Go program
go run main.go
# Build executable
go build
go build -o myapp  # Custom name
# Install binary to GOPATH/bin
go install
# Format code
go fmt ./...
# Vet code for issues
go vet ./...
# Clean build cache
go clean -cache