Golang для начинающих: полное руководство 2026

Golang для начинающих: полное руководство 2026

Golang для начинающих: установка, синтаксис, структуры данных, горутины. Пошаговое руководство с примерами кода для старта в Go разработке.

Golang (или просто Go) — это язык программирования от Google, который захватил мир backend-разработки. Docker, Kubernetes, Terraform — всё это написано на Go. И если ты хочешь войти в мир современной разработки, Golang — отличный выбор.

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

Почему Golang?

Прежде чем погружаться в синтаксис, давай разберёмся — а зачем вообще учить ещё один язык?

Простота изучения

Golang создавался с философией “меньше — лучше”. Здесь нет классов, наследования, исключений в привычном понимании. Весь язык можно изучить за пару недель.

// Вот так выглядит Hello World на Go
package main

import "fmt"

func main() {
    fmt.Println("Привет, Golang!")
}

Производительность

Go компилируется в нативный код. Это значит — скорость близкая к C/C++, но с удобством Python. Никаких виртуальных машин, никакого JIT.

Встроенная конкурентность

Горутины — киллер-фича Go. Запустить тысячи параллельных задач? Легко. Об этом я подробно писал в статье про конкурентность в Go: channels vs sync .

Большое сообщество и вакансии

Golang входит в топ-10 языков по популярности. Вакансий много, зарплаты высокие, а конкуренция ниже чем в Python или JavaScript.

Установка Golang

Windows

  1. Скачай установщик с официального сайта
  2. Запусти .msi файл
  3. Проверь установку:
go version
# go version go1.22.0 windows/amd64

macOS

# Через Homebrew (рекомендую)
brew install go

# Проверка
go version

Linux

# Ubuntu/Debian
sudo apt update
sudo apt install golang-go

# Или скачай напрямую
wget https://golang.org/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

Настройка окружения

После установки добавь в .bashrc или .zshrc:

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

Первая программа на Golang

Создадим классический Hello World и разберём каждую строку.

package main

import "fmt"

func main() {
    fmt.Println("Привет, Golang!")
}

Разбор кода

  • package main — каждый Go-файл принадлежит пакету. main — точка входа программы
  • import "fmt" — импортируем стандартный пакет для форматированного вывода
  • func main() — главная функция, с неё начинается выполнение
  • fmt.Println() — вывод строки с переносом

Запуск программы

# Создай файл main.go с кодом выше
go run main.go
# Привет, Golang!

# Или скомпилируй в бинарник
go build main.go
./main

Переменные и типы данных

Go — строго типизированный язык. Это значит, что каждая переменная имеет тип, и компилятор следит за его соблюдением.

Объявление переменных

// Явное указание типа
var name string = "Алексей"
var age int = 30

// Короткое объявление (рекомендуется)
name := "Алексей"
age := 30

// Множественное объявление
var (
    firstName = "Алексей"
    lastName  = "Горбунов"
    isActive  = true
)

Базовые типы

// Числа
var i int = 42           // int, int8, int16, int32, int64
var f float64 = 3.14     // float32, float64
var c complex128 = 1+2i  // комплексные числа

// Строки
var s string = "Hello"

// Булевы
var b bool = true

// Байты и руны
var byte byte = 'A'      // alias для uint8
var r rune = 'Я'         // alias для int32 (Unicode)

Константы

const Pi = 3.14159
const (
    StatusOK    = 200
    StatusError = 500
)

// iota — автоинкремент для констант
const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
)

Структуры данных Golang

Массивы

Массивы в Go имеют фиксированную длину:

// Массив из 5 элементов
var arr [5]int = [5]int{1, 2, 3, 4, 5}

// Короткая запись
arr := [5]int{1, 2, 3, 4, 5}

// Автоопределение длины
arr := [...]int{1, 2, 3, 4, 5}

fmt.Println(arr[0])  // 1
fmt.Println(len(arr)) // 5

Слайсы (срезы)

Слайсы — динамические массивы, используются чаще:

// Создание слайса
slice := []int{1, 2, 3, 4, 5}

// Через make
slice := make([]int, 5)      // длина 5
slice := make([]int, 5, 10)  // длина 5, ёмкость 10

// Добавление элементов
slice = append(slice, 6, 7, 8)

// Срезы из массива
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4]  // [2, 3, 4]

Мапы (словари)

// Создание мапы
m := map[string]int{
    "apple":  5,
    "banana": 3,
}

// Через make
m := make(map[string]int)

// Операции
m["orange"] = 7        // добавление
value := m["apple"]    // получение
delete(m, "banana")    // удаление

// Проверка существования ключа
value, exists := m["apple"]
if exists {
    fmt.Println("Найдено:", value)
}

Функции в Golang

Базовый синтаксис

// Простая функция
func greet(name string) {
    fmt.Println("Привет,", name)
}

// Функция с возвратом
func add(a, b int) int {
    return a + b
}

// Множественный возврат
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("деление на ноль")
    }
    return a / b, nil
}

Именованные возвращаемые значения

func rectangle(width, height float64) (area, perimeter float64) {
    area = width * height
    perimeter = 2 * (width + height)
    return // naked return
}

Вариативные функции

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

// Вызов
sum(1, 2, 3, 4, 5)  // 15

Анонимные функции и замыкания

// Анонимная функция
func() {
    fmt.Println("Я анонимная!")
}()

// Замыкание
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

c := counter()
fmt.Println(c())  // 1
fmt.Println(c())  // 2

Структуры и методы

Определение структуры

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

// Создание экземпляра
user := User{
    ID:    1,
    Name:  "Алексей",
    Email: "alex@example.com",
}

// Доступ к полям
fmt.Println(user.Name)

Методы структур

type Rectangle struct {
    Width  float64
    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
}

rect := Rectangle{10, 5}
fmt.Println(rect.Area())  // 50
rect.Scale(2)
fmt.Println(rect.Area())  // 200

Встраивание (композиция)

type Person struct {
    Name string
    Age  int
}

type Employee struct {
    Person        // встраивание
    Position string
    Salary   int
}

emp := Employee{
    Person:   Person{Name: "Алексей", Age: 30},
    Position: "Developer",
    Salary:   200000,
}

// Доступ к полям Person напрямую
fmt.Println(emp.Name)  // Алексей

Интерфейсы в Golang

Интерфейсы — мощный инструмент для абстракции. В Go они реализуются неявно.

// Определение интерфейса
type Writer interface {
    Write(data []byte) error
}

// Структура, реализующая интерфейс
type FileWriter struct {
    filename string
}

func (fw FileWriter) Write(data []byte) error {
    return os.WriteFile(fw.filename, data, 0644)
}

// Использование
func save(w Writer, data []byte) error {
    return w.Write(data)
}

fw := FileWriter{"output.txt"}
save(fw, []byte("Hello!"))

Пустой интерфейс

// interface{} или any — принимает любой тип
func printAnything(v interface{}) {
    fmt.Printf("Тип: %T, Значение: %v\n", v, v)
}

printAnything(42)
printAnything("hello")
printAnything([]int{1, 2, 3})

Type assertion

var i interface{} = "hello"

// Приведение типа
s := i.(string)
fmt.Println(s)  // hello

// Безопасное приведение
s, ok := i.(string)
if ok {
    fmt.Println("Это строка:", s)
}

// Type switch
switch v := i.(type) {
case string:
    fmt.Println("Строка:", v)
case int:
    fmt.Println("Число:", v)
default:
    fmt.Println("Неизвестный тип")
}

Обработка ошибок

В Go нет исключений. Вместо этого — явная обработка ошибок через возврат error.

func readFile(filename string) ([]byte, error) {
    data, err := os.ReadFile(filename)
    if err != nil {
        return nil, fmt.Errorf("не удалось прочитать файл %s: %w", filename, err)
    }
    return data, nil
}

// Использование
data, err := readFile("config.json")
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(data))

Создание своих ошибок

import "errors"

var ErrNotFound = errors.New("не найдено")

func findUser(id int) (*User, error) {
    // ... поиск
    if user == nil {
        return nil, ErrNotFound
    }
    return user, nil
}

// Проверка типа ошибки
if errors.Is(err, ErrNotFound) {
    fmt.Println("Пользователь не найден")
}

О том, как избежать типичных ошибок при написании кода, читай в моей статье про антипаттерны Go .

Горутины и каналы

Конкурентность — главная фича Go. Горутины — легковесные потоки, каналы — способ коммуникации между ними.

Горутины

func sayHello(name string) {
    fmt.Println("Привет,", name)
}

func main() {
    // Запуск горутины
    go sayHello("Алексей")
    go sayHello("Мария")
    
    // Ждём завершения (плохой способ)
    time.Sleep(time.Second)
}

Каналы

func main() {
    // Создание канала
    ch := make(chan string)
    
    // Отправка в горутине
    go func() {
        ch <- "Сообщение из горутины"
    }()
    
    // Получение
    msg := <-ch
    fmt.Println(msg)
}

Буферизованные каналы

// Канал с буфером на 3 элемента
ch := make(chan int, 3)

ch <- 1
ch <- 2
ch <- 3
// ch <- 4  // заблокируется, буфер полон

fmt.Println(<-ch)  // 1

WaitGroup для синхронизации

import "sync"

func main() {
    var wg sync.WaitGroup
    
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            fmt.Println("Горутина", n)
        }(i)
    }
    
    wg.Wait()  // ждём завершения всех горутин
    fmt.Println("Все горутины завершены")
}

Подробнее о синхронизации и выборе между channels и sync читай в статье про конкурентность в Go .

Работа с JSON

import "encoding/json"

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email,omitempty"`
}

// Сериализация (struct -> JSON)
user := User{ID: 1, Name: "Алексей"}
data, err := json.Marshal(user)
// {"id":1,"name":"Алексей"}

// Десериализация (JSON -> struct)
var user2 User
err = json.Unmarshal(data, &user2)

Работа с HTTP

HTTP-сервер

import "net/http"

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Привет, %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", helloHandler)
    
    fmt.Println("Сервер запущен на :8080")
    http.ListenAndServe(":8080", nil)
}

HTTP-клиент

resp, err := http.Get("https://api.example.com/users")
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))

Тестирование в Golang

Go имеет встроенный инструментарий для тестирования. Подробнее об этом я написал в статье про тестирование в Go .

// math.go
package math

func Add(a, b int) int {
    return a + b
}

// math_test.go
package math

import "testing"

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

Запуск тестов:

go test ./...
go test -v ./...  # подробный вывод
go test -cover    # покрытие кода

Модули и зависимости

Инициализация модуля

mkdir myproject
cd myproject
go mod init github.com/username/myproject

Добавление зависимостей

go get github.com/gin-gonic/gin
go get github.com/lib/pq

go.mod файл

module github.com/username/myproject

go 1.22

require (
    github.com/gin-gonic/gin v1.9.1
    github.com/lib/pq v1.10.9
)

Что изучать дальше?

После освоения базового синтаксиса, рекомендую углубиться в:

  1. Конкурентность — паттерны работы с горутинами и каналами
  2. Тестирование — table-driven tests, моки, бенчмарки
  3. Веб-фреймворки — Gin, Echo, Fiber
  4. Базы данных — GORM, sqlx
  5. gRPC — для микросервисной архитектуры (читай мою статью про gRPC в Go )

Полезные ресурсы

Заключение

Golang — это язык, который делает разработку приятной. Простой синтаксис, быстрая компиляция, мощная стандартная библиотека. Начни с простых проектов — CLI-утилиты, HTTP-серверы, парсеры — и постепенно переходи к более сложным задачам.

Если у тебя есть вопросы — пиши в комментариях. И не забудь почитать другие мои статьи про Go — там много практических советов из реального опыта.

Удачи в изучении Golang! 🚀