Einführung in Go
Go (Golang) для начинающих: язык Google для облаков и серверов
Добро пожаловать в мир Go! Если ты хочешь создавать быстрые серверы, облачные сервисы и инструменты командной строки — Go создан именно для этого. Молодой, простой и невероятно производительный язык от Google.
История Go: как Google создал новый язык
Представь себе 2007 год. В Google работают тысячи программистов. Они пишут на C++ и Java, но сталкиваются с проблемами: C++ компилируется долго, Java перегружена. Три выдающихся инженера решают создать что-то новое:
- Роберт Гриземер — работал над JavaScript-движком V8 (в Chrome)
- Роб Пайк — создатель операционной системы Plan 9, легенда Unix
- Кен Томпсон — создатель языка C и операционной системы Unix. Без него не было бы ни Linux, ни macOS!
В 2009 году Google анонсировал Go. В 2012 году вышла стабильная версия 1.0. Сегодня это один из самых востребованных языков в облачной разработке.
Философия Go: простота превыше всего
Создатели поставили цель: язык должен быть радикально простым. Принципы Go:
- Минимализм — мало ключевых слов, нет классов, нет исключений, нет перегрузки операторов
- Явность — код читается буквально, никакой магии
- Быстрая компиляция — секунды даже в больших проектах
- Встроенная конкурентность — горутины и каналы встроены в язык
Где используется Go
🐳 Docker и Kubernetes
Docker и Kubernetes — оба написаны на Go. Это два важнейших инструмента современной облачной разработки.
🌐 Backend-серверы
Google, Uber, Dropbox, Twitch используют Go для своих серверов. Go обрабатывает миллионы запросов в секунду с минимальными ресурсами.
🛠️ CLI-инструменты
Hugo (генератор сайтов), Terraform (инфраструктура как код), CockroachDB написаны на Go.
Установка Go
# Проверка установки
go version
# go version go1.22.0 linux/amd64
# Создать проект
mkdir hello-go && cd hello-go
go mod init hello
Первая программа
Создай файл main.go:
package main
import "fmt"
func main() {
fmt.Println("Привет, мир!")
}
Запускаем:
go run main.go
# Привет, мир!
Разбор каждой строки
- package main — каждый файл Go принадлежит пакету. Пакет
main— это исполняемая программа. - import "fmt" — импортируем пакет fmt (format) для ввода-вывода.
- func main() { — точка входа. С этой функции всё начинается.
- fmt.Println("Привет, мир!") — выводим строку с переводом строки в конце.
- } — В Go открывающая скобка ВСЕГДА на той же строке, иначе ошибка!
Пакет fmt: форматированный вывод
package main
import "fmt"
func main() {
// Println — вывод со знаком новой строки
fmt.Println("Строка 1")
fmt.Println("Строка 2")
// Print — без новой строки
fmt.Print("Без ")
fmt.Print("переноса ")
fmt.Println("строки")
// Printf — форматированный вывод
name := "Дима"
age := 16
fmt.Printf("Меня зовут %s, мне %d лет\n", name, age)
// Sprintf — форматирование в строку (не вывод)
message := fmt.Sprintf("Привет, %s!", name)
fmt.Println(message)
// Основные форматы:
fmt.Printf("%d\n", 42) // целое число
fmt.Printf("%f\n", 3.14) // число с плавающей точкой
fmt.Printf("%.2f\n", 3.14159) // 2 знака после запятой
fmt.Printf("%s\n", "строка") // строка
fmt.Printf("%t\n", true) // булево
fmt.Printf("%v\n", 42) // любой тип (универсальный)
fmt.Printf("%T\n", 42) // тип переменной
}
Ввод от пользователя
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Как тебя зовут? ")
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
fmt.Printf("Привет, %s! Добро пожаловать в Go!\n", name)
// Простой ввод числа
var age int
fmt.Print("Сколько тебе лет? ")
fmt.Scan(&age) // & — адрес переменной (указатель)
fmt.Printf("Тебе %d лет\n", age)
}
Структура Go-проекта
my-project/
├── go.mod # Описание модуля и зависимостей
├── go.sum # Контрольные суммы зависимостей
├── main.go # Основной файл (точка входа)
├── utils/
│ └── helpers.go # Вспомогательные функции
└── models/
└── user.go # Модели данных
// go.mod выглядит так:
module hello
go 1.22
Типичные ошибки новичков
Ошибка 1: Импорт без использования
// ОШИБКА! Go не компилируется если импорт не используется
import "fmt"
import "math" // Ошибка если math нигде не используется
// ПРАВИЛЬНО: удали неиспользуемые импорты
import "fmt"
Ошибка 2: Переменная без использования
func main() {
x := 5 // ОШИБКА! 'x' declared but not used
fmt.Println("hello")
// ПРАВИЛЬНО:
x := 5
fmt.Println(x)
}
Ошибка 3: Открывающая скобка на новой строке
// ОШИБКА синтаксиса!
func main()
{
fmt.Println("hello")
}
// ПРАВИЛЬНО: скобка на той же строке
func main() {
fmt.Println("hello")
}
Команды go tool
go run main.go # Запустить без компиляции
go build # Скомпилировать
go build -o app # Скомпилировать с именем 'app'
go test ./... # Запустить тесты
go fmt ./... # Отформатировать код
go vet ./... # Проверить код на ошибки
go mod tidy # Обновить зависимости
Итого
- ✅ Go создан в Google в 2009 году Робертом Гриземером, Робом Пайком и Кеном Томпсоном
- ✅ Go используется в Docker, Kubernetes, backend-серверах и CLI-инструментах
- ✅ Философия Go: простота, явность, скорость компиляции
- ✅ Каждая программа начинается с
package mainи функцииfunc main() - ✅
fmt.Println— вывод строки,fmt.Printf— форматированный вывод - ✅ В Go нельзя импортировать пакеты или объявлять переменные, которые не используются
- ✅ Открывающая фигурная скобка всегда на той же строке
Разбор каждой строки программы
package main // (1)
import "fmt" // (2)
func main() { // (3)
fmt.Println("Привет, мир!") // (4)
} // (5)
- (1) package main — каждый файл Go принадлежит пакету.
main— специальный пакет для исполняемых программ. Пакет — это как папка с кодом. - (2) import "fmt" — импортируем пакет
fmt(format). Это стандартная библиотека для форматированного ввода-вывода. В Go нельзя импортировать что-то и не использовать — получишь ошибку компиляции! - (3) func main() { — объявляем функцию
main. Это точка входа программы. Открывающая скобка ОБЯЗАНА быть на той же строке — иначе синтаксическая ошибка! - (4) fmt.Println("Привет, мир!") — вызываем функцию
Printlnиз пакетаfmt. Она выводит строку и добавляет символ новой строки. - (5) } — закрывающая скобка функции.
Пакет fmt: все способы вывода
package main
import "fmt"
func main() {
name := "Дима"
age := 16
gpa := 4.75
// Println — вывод со знаком новой строки
fmt.Println("Привет!")
fmt.Println(name, age, gpa) // Пробелы между значениями автоматически
// Print — вывод без новой строки
fmt.Print("Без ")
fmt.Print("переноса")
fmt.Println() // Просто новая строка
// Printf — форматированный вывод
fmt.Printf("Меня зовут %s, мне %d лет, GPA: %.2f\n", name, age, gpa)
// Основные форматные спецификаторы:
fmt.Printf("%d\n", 42) // Целое число
fmt.Printf("%f\n", 3.14) // Число с точкой
fmt.Printf("%.2f\n", 3.14159) // 2 знака после точки: 3.14
fmt.Printf("%s\n", "строка") // Строка
fmt.Printf("%q\n", "строка") // Строка в кавычках: "строка"
fmt.Printf("%t\n", true) // Булево: true/false
fmt.Printf("%v\n", 42) // Любой тип (универсальный)
fmt.Printf("%T\n", 42) // Тип переменной: int
fmt.Printf("%b\n", 10) // Двоичное: 1010
fmt.Printf("%x\n", 255) // Шестнадцатеричное: ff
fmt.Printf("%05d\n", 42) // Ширина 5, с нулями: 00042
// Sprintf — форматирование в строку
msg := fmt.Sprintf("Пользователь %s (%d лет)", name, age)
fmt.Println(msg) // Пользователь Дима (16 лет)
}
Ввод от пользователя
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Ввод строки
fmt.Print("Как тебя зовут? ")
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name) // Убираем пробелы и \n
fmt.Printf("Привет, %s!\n", name)
// Ввод числа
fmt.Print("Сколько тебе лет? ")
ageStr, _ := reader.ReadString('\n')
ageStr = strings.TrimSpace(ageStr)
age, err := strconv.Atoi(ageStr)
if err != nil {
fmt.Println("Ошибка: введи число!")
return
}
fmt.Printf("Тебе %d лет.\n", age)
if age >= 18 {
fmt.Println("Ты совершеннолетний!")
} else {
fmt.Printf("До 18 лет осталось %d лет.\n", 18 - age)
}
}
Структура Go-проекта
my-project/
├── go.mod # Описание модуля и зависимостей
├── go.sum # Контрольные суммы (автогенерируется)
├── main.go # Точка входа программы
├── utils/
│ └── helpers.go # Вспомогательные функции
└── models/
└── user.go # Модели данных
// go.mod — файл модуля
module github.com/myuser/my-project
go 1.22
require (
github.com/gin-gonic/gin v1.9.0 // внешняя зависимость
)
Go Modules: управление зависимостями
# Инициализировать модуль
go mod init github.com/myname/myproject
# Добавить зависимость
go get github.com/gin-gonic/gin
# Обновить зависимости
go mod tidy
# Список зависимостей
go list -m all
Полезные команды go tool
go run main.go # Запустить без компиляции (для разработки)
go build # Скомпилировать в текущей папке
go build -o myapp # Скомпилировать с именем 'myapp'
go test ./... # Запустить все тесты
go fmt ./... # Отформатировать весь код (ОБЯЗАТЕЛЬНО!)
go vet ./... # Статический анализатор — находит ошибки
go doc fmt.Println # Документация функции
go env # Показать переменные окружения Go
go clean # Удалить скомпилированные файлы
Типичные ошибки новичков
Ошибка 1: Неиспользуемый импорт
import "fmt"
import "math" // ОШИБКА если math нигде не используется!
// ПРАВИЛЬНО: удали неиспользуемые импорты
// В VS Code с расширением Go это делается автоматически
Ошибка 2: Объявленная переменная не используется
func main() {
x := 5 // ОШИБКА: x declared and not used
fmt.Println("hi")
}
// ПРАВИЛЬНО:
func main() {
x := 5
fmt.Println(x) // Используем x
}
Ошибка 3: Скобка на новой строке
// ОШИБКА синтаксис!
func main()
{
fmt.Println("hi")
}
// ПРАВИЛЬНО: открывающая скобка на той же строке
func main() {
fmt.Println("hi")
}
Ошибка 4: Неправильное присваивание nil
var x int = nil // ОШИБКА! int не может быть nil
var p *int = nil // OK — указатель может быть nil
var s []int = nil // OK — срез может быть nil
Почему Go так популярен: сравнение
Чем Go отличается от других языков:
- Go vs Python: Go в 10-100 раз быстрее, компилируемый, статически типизированный. Python проще для начала, но медленнее.
- Go vs Java: Go быстрее компилируется, занимает меньше памяти, нет JVM. Java богаче экосистемой.
- Go vs C++: Go значительно проще, безопаснее (сборщик мусора), быстрее компилируется. C++ быстрее в критичных по производительности местах.
- Go vs Rust: Go проще в изучении, Rust безопаснее по памяти (без сборщика мусора).
Итого
- ✅ Go создан в Google в 2009 году Гриземером, Пайком и Томпсоном
- ✅ Используется в Docker, Kubernetes, backend-серверах, DevOps инструментах
- ✅ Философия: простота, явность, скорость компиляции
- ✅ Каждый файл начинается с
package - ✅ Точка входа —
func main()в пакетеmain - ✅
fmt.Println— вывод строки,fmt.Printf— форматированный вывод - ✅ Нельзя импортировать неиспользуемые пакеты
- ✅ Нельзя объявлять неиспользуемые переменные
- ✅ Открывающая скобка — только на той же строке что и заголовок функции
- ✅
go run— запустить,go build— скомпилировать,go fmt— форматировать
Стандартная библиотека Go
package main
import (
"fmt"
"math"
"sort"
"strings"
"time"
"unicode"
)
func main() {
// math — математика
fmt.Printf("Pi: %.5f\n", math.Pi)
fmt.Printf("Sqrt(2): %.5f\n", math.Sqrt(2))
fmt.Printf("Pow(2,10): %.0f\n", math.Pow(2, 10))
fmt.Printf("Abs(-42): %.0f\n", math.Abs(-42))
// strings — работа со строками
s := " Привет, Мир! "
fmt.Println(strings.TrimSpace(s)) // Привет, Мир!
fmt.Println(strings.ToUpper(s)) // всё заглавными
fmt.Println(strings.Contains(s, "Мир")) // true
fmt.Println(strings.Replace(s, "Мир", "Go", 1))
parts := strings.Split("a,b,c", ",")
fmt.Println(parts) // [a b c]
fmt.Println(strings.Join(parts, " - ")) // a - b - c
// unicode — работа с символами
fmt.Println(unicode.IsLetter('А')) // true
fmt.Println(unicode.IsDigit('5')) // true
// sort — сортировка
nums := []int{5, 2, 8, 1, 9, 3}
sort.Ints(nums)
fmt.Println(nums) // [1 2 3 5 8 9]
words := []string{"Ялта", "Москва", "Астрахань"}
sort.Strings(words)
fmt.Println(words) // [Астрахань Москва Ялта]
// time — дата и время
now := time.Now()
fmt.Println(now.Format("02.01.2006 15:04:05"))
tomorrow := now.Add(24 * time.Hour)
fmt.Println(tomorrow.Format("02.01.2006"))
}