Как: полное руководство по Go с примерами кода. От "Hello, World!" до конкурентного сервера

Исчерпывающее введение в язык программирования Go: синтаксис, типы, функции, структуры, интерфейсы, срезы, карты, горутины, каналы и практический пример TCP-сервера.
Go (или Golang) — это язык программирования, созданный в Google для построения простого, эффективного и надежного программного обеспечения. Его философия основана на минимализме, явности и первоклассной поддержке конкурентности. Это руководство проведет вас от самых основ до создания сетевого сервера, раскрывая ключевые концепции языка через практические примеры кода.

Начнем с фундамента. Программа на Go организована в пакеты (packages). Точка входа — функция `main` в пакете `main`. Вот классический пример:

```go
package main

import "fmt"

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

Компиляция и запуск: `go run hello.go`. Для создания бинарного файла: `go build hello.go`. Go — язык со статической типизацией. Основные типы: `bool`, `string`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `float32`, `float64`, `complex64`, `complex128`. Объявление переменной: `var name string = "Go"`. Сокращенная форма внутри функции: `name := "Go"`. Константы: `const Pi = 3.14`.

Управляющие конструкции знакомы, но со своими особенностями. Цикл `for` — единственный цикл в Go, но он гибок.
```go
// Классический цикл
for i := 0; i < 5; i++ {
 fmt.Println(i)
}

// Цикл по диапазону (range)
nums := []int{1, 2, 3}
for index, value := range nums {
 fmt.Printf("index: %d, value: %d\n", index, value)
}

// Бесконечный цикл
for {
 // break для выхода
}
```
Условный оператор `if` может включать инструкцию инициализации:
```go
if err := someFunction(); err != nil {
 fmt.Println("Error:", err)
}
```
`switch` в Go более мощный, чем во многих языках, и не требует `break`.

Функции — граждане первого класса. Они могут возвращать несколько значений, что часто используется для возврата результата и ошибки.
```go
func divide(a, b float64) (float64, error) {
 if b == 0.0 {
 return 0, fmt.Errorf("cannot divide by zero")
 }
 return a / b, nil
}
```
Именованные возвращаемые значения (named return values) позволяют заранее объявить возвращаемые переменные в сигнатуре функции.

Структуры (structs) — это типы, собирающие вместе поля. Методы определяются отдельно, с получателем (receiver).
```go
type Rectangle struct {
 Width, Height float64
}

// Метод с получателем по значению
func (r Rectangle) Area() float64 {
 return r.Width * r.Height
}

// Метод с получателем по указателю (может изменять структуру)
func (r *Rectangle) Scale(factor float64) {
 r.Width *= factor
 r.Height *= factor
}
```
Интерфейсы (interfaces) в Go реализуются неявно. Тип реализует интерфейс просто путем реализации всех его методов.
```go
type Shape interface {
 Area() float64
}

func printArea(s Shape) {
 fmt.Println("Area:", s.Area())
}
// Rectangle автоматически реализует Shape, т.к. имеет метод Area().
```

Работа с коллекциями. Срезы (slices) — это ключевой тип для работы с последовательностями. Они динамические и строятся поверх массивов.
```go
// Создание среза
slice := []string{"a", "b", "c"}
slice = append(slice, "d") // Добавление элемента

// Итерация
for i, v := range slice {
 // ...
}
```
Карты (maps): `m := make(map[string]int); m["key"] = 42`.

Теперь перейдем к одной из самых сильных сторон Go — конкурентности (concurrency). Примитив для этого — горутины (goroutines). Это легковесные потоки, управляемые рантаймом Go. Запускаются с помощью ключевого слова `go`.
```go
func say(s string) {
 for i := 0; i < 3; i++ {
 time.Sleep(100 * time.Millisecond)
 fmt.Println(s)
 }
}

func main() {
 go say("world") // запуск горутины
 say("hello")
}
```
Для связи между горутинами используются каналы (channels). Канал — это типизированный conduit, через который можно отправлять и получать значения.
```go
ch := make(chan int)

// Горутина отправляет данные в канал
go func() {
 ch
410 5

Комментарии (7)

avatar
8uamdc 27.03.2026
Спасибо за структурированный материал! Как junior-разработчик, нашёл для себя много полезных паттернов в коде.
avatar
veahj3ki 27.03.2026
Отличное руководство для старта! Особенно понравились примеры с горутинами и каналами — наконец-то разобрался.
avatar
ulk6vh4eeqn 28.03.2026
После прочтения захотелось переписать свой микросервис на Go. Философия языка действительно впечатляет своей простотой.
avatar
xi9xrpggw4l 28.03.2026
Конкурентность объяснена доступно, но хотелось бы больше практических кейсов: пулы воркеров, graceful shutdown.
avatar
wu4rsrqgs83 29.03.2026
Пример с HTTP-сервером слишком упрощён. В реальном проекте нужно добавить middleware, логирование и обработку ошибок.
avatar
bmvn4mj3m1g7 30.03.2026
Автор упустил важный момент по управлению зависимостями через go.mod. Без этого сложно представить современный Go.
avatar
8olh2lcl9 30.03.2026
Статья хорошая, но не хватает сравнения с другими языками. Почему именно Go, а не Rust или Python для серверов?
Вы просмотрели все комментарии