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

Golang для начинающих: установка, синтаксис, структуры данных, горутины. Пошаговое руководство с примерами кода для старта в Go разработке.
- теги
- #Golang #Go #Программирование #Для Начинающих #Tutorial
- категории
- Programming
- опубликовано
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
- Скачай установщик с официального сайта
- Запусти .msi файл
- Проверь установку:
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
)
Что изучать дальше?
После освоения базового синтаксиса, рекомендую углубиться в:
- Конкурентность — паттерны работы с горутинами и каналами
- Тестирование — table-driven tests, моки, бенчмарки
- Веб-фреймворки — Gin, Echo, Fiber
- Базы данных — GORM, sqlx
- gRPC — для микросервисной архитектуры (читай мою статью про gRPC в Go )
Полезные ресурсы
- Официальная документация
- Go by Example
- Effective Go
- Go Playground — песочница для экспериментов
Заключение
Golang — это язык, который делает разработку приятной. Простой синтаксис, быстрая компиляция, мощная стандартная библиотека. Начни с простых проектов — CLI-утилиты, HTTP-серверы, парсеры — и постепенно переходи к более сложным задачам.
Если у тебя есть вопросы — пиши в комментариях. И не забудь почитать другие мои статьи про Go — там много практических советов из реального опыта.
Удачи в изучении Golang! 🚀