Готовые программы на Golang

Go (или Golang) — это язык программирования, разработанный компанией Google, который сочетает в себе производительность компилируемых языков и удобство динамических языков. Он широко используется для создания высокопроизводительных серверных приложений, микросервисов, а также в области облачных технологий и обработки данных.

В этой статье рассмотрим несколько примеров программ на Go, чтобы показать основные принципы работы с этим языком, его особенности и преимущества. Представляем готовые программы на Golang, которые вы можете скопировать себе и поизучать.


👣 Golang Go – авторский канал, посвященный Go разработке, Devops и созданию высоконагруженных сервисов.

1. Простая программа: “Hello, World!”

Как и в любом языке программирования, начнём с самой простой программы, которая выводит строку на экран:

goКопировать кодpackage main

import "fmt"

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

Пояснение:

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

2. Ввод и вывод данных

Давайте напишем программу, которая запрашивает у пользователя его имя и выводит приветствие:

goКопировать кодpackage main

import (
	"fmt"
)

func main() {
	var name string
	fmt.Print("Введите ваше имя: ")
	fmt.Scanln(&name)
	fmt.Printf("Привет, %s!\n", name)
}

Пояснение:

  • var name string — объявление переменной name типа string.
  • fmt.Print() — выводит текст без перевода строки.
  • fmt.Scanln(&name) — считывает строку с клавиатуры и сохраняет её в переменную name.
  • fmt.Printf() — выводит форматированную строку, подставляя значение переменной в место %s.

3. Простой калькулятор

Теперь создадим программу, которая выполняет сложение двух чисел, введённых пользователем:

goКопировать кодpackage main

import (
	"fmt"
)

func main() {
	var num1, num2 float64
	fmt.Print("Введите первое число: ")
	fmt.Scanln(&num1)
	fmt.Print("Введите второе число: ")
	fmt.Scanln(&num2)

	sum := num1 + num2
	fmt.Printf("Сумма чисел: %.2f\n", sum)
}

Пояснение:

  • var num1, num2 float64 — объявление двух переменных типа float64 для хранения чисел с плавающей запятой.
  • Ввод данных осуществляется через fmt.Scanln(&num1) и fmt.Scanln(&num2).
  • Результат вычисления выводится с помощью fmt.Printf() с форматом, ограничивающим вывод до двух знаков после запятой (%.2f).

4. Нахождение факториала числа

Пример программы, которая вычисляет факториал числа с помощью рекурсии:

goКопировать кодpackage main

import (
	"fmt"
)

func factorial(n int) int {
	if n == 0 {
		return 1
	}
	return n * factorial(n-1)
}

func main() {
	var num int
	fmt.Print("Введите число для нахождения факториала: ")
	fmt.Scanln(&num)

	fmt.Printf("Факториал числа %d равен %d\n", num, factorial(num))
}

Пояснение:

  • Функция factorial(n int) вычисляет факториал числа с помощью рекурсии. Когда n == 0, возвращается 1, иначе возвращается n * factorial(n-1).
  • Ввод числа осуществляется через fmt.Scanln(&num), после чего результат выводится через fmt.Printf().

5. Работа с массивами

В Go массивы имеют фиксированный размер. Рассмотрим пример программы, которая находит сумму элементов массива:

goКопировать кодpackage main

import "fmt"

func main() {
	var numbers = [5]int{1, 2, 3, 4, 5}
	var sum int

	for _, number := range numbers {
		sum += number
	}

	fmt.Printf("Сумма элементов массива: %d\n", sum)
}

Пояснение:

  • var numbers = [5]int{1, 2, 3, 4, 5} — создание массива из 5 элементов.
  • for _, number := range numbers — цикл, который итерирует по всем элементам массива.
    • _ используется для игнорирования индекса элемента (мы его не используем).
    • number — значение текущего элемента массива.
  • Суммирование элементов массива происходит в теле цикла, результат выводится через fmt.Printf().

6. Использование слайсов

Слайсы — это динамические массивы в Go. Они могут изменять свой размер во время выполнения программы. Рассмотрим пример программы, которая добавляет элементы в слайс:

Готовые программы на Golang
Готовые программы на Golang
goКопировать кодpackage main

import "fmt"

func main() {
	var numbers []int
	numbers = append(numbers, 1, 2, 3, 4, 5)

	fmt.Println("Содержимое слайса:", numbers)
}

Пояснение:

  • var numbers []int — объявление слайса целых чисел.
  • append(numbers, 1, 2, 3, 4, 5) — добавление элементов в слайс.
  • fmt.Println() выводит содержимое слайса на экран.

7. Создание простого HTTP-сервера

Go идеально подходит для создания высокопроизводительных веб-сервисов. Рассмотрим пример создания простого HTTP-сервера, который будет отдавать страницу “Hello, World!”:

goКопировать кодpackage main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Hello, World!")
}

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("Запуск сервера на порту 8080...")
	http.ListenAndServe(":8080", nil)
}

Пояснение:

  • http.HandleFunc("/", handler) — регистрирует обработчик запросов, который будет вызываться при обращении к корневому URL (/).
  • fmt.Fprintln(w, "Hello, World!") — отправляет ответ с текстом “Hello, World!” клиенту.
  • http.ListenAndServe(":8080", nil) — запускает HTTP-сервер на порту 8080.

Запустив эту программу, можно обратиться к серверу по адресу http://localhost:8080 и увидеть ответ “Hello, World!”.

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

Одна из ключевых особенностей Go — это поддержка конкурентности с помощью горутин и каналов. Рассмотрим пример, где несколько горутин одновременно выполняют задачи:

goКопировать кодpackage main

import (
	"fmt"
	"time"
)

func sayHello() {
	time.Sleep(2 * time.Second)
	fmt.Println("Привет из горутины!")
}

func main() {
	go sayHello() // Запускаем горутину

	fmt.Println("Основная программа продолжает работать...")
	time.Sleep(3 * time.Second) // Ждем, чтобы горутина успела завершиться
}

Пояснение:

  • go sayHello() — запускает функцию sayHello в новой горутине.
  • time.Sleep(2 * time.Second) — имитирует задержку в горутине.
  • main() также выполняется, не ожидая завершения горутины, но мы добавляем задержку, чтобы горутина успела выполнить свою работу.

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

Давайте создадим более сложную программу на Go, которая будет выполнять задачу управления задачами (Task Manager). В этом примере мы будем использовать базу данных SQLite для хранения данных о задачах, а также реализуем API с использованием фреймворка Gin для создания веб-приложения. Программа будет поддерживать следующие действия:

  • Добавление новой задачи.
  • Просмотр всех задач.
  • Обновление задачи.
  • Удаление задачи.

Мы будем использовать Gin для построения REST API и SQLite для хранения данных о задачах.

Шаги:

  1. Установим зависимости.
  2. Создадим структуру проекта.
  3. Реализуем работу с базой данных SQLite.
  4. Напишем код для обработки HTTP-запросов.
  5. Реализуем взаимодействие с API.

1. Установка зависимостей

Для начала установим нужные зависимости:

  1. Gin — для создания REST API.
  2. SQLite — для работы с базой данных.
bashКопировать кодgo get -u github.com/gin-gonic/gin
go get -u github.com/mattn/go-sqlite3

2. Структура проекта

Предположим, структура проекта будет такой:

bashКопировать кодtask-manager/
│
├── main.go        # Основной файл программы
├── database.go    # Работа с базой данных
└── models.go      # Структуры данных

3. Реализация работы с базой данных (database.go)

Этот файл будет отвечать за подключение к базе данных SQLite и выполнение SQL-запросов.

goКопировать кодpackage main

import (
	"database/sql"
	"log"

	_ "github.com/mattn/go-sqlite3"
)

var db *sql.DB

// Инициализация базы данных
func initDB() {
	var err error
	db, err = sql.Open("sqlite3", "./tasks.db")
	if err != nil {
		log.Fatal(err)
	}

	// Создание таблицы, если она еще не существует
	query := `CREATE TABLE IF NOT EXISTS tasks (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		title TEXT NOT NULL,
		description TEXT,
		done BOOLEAN NOT NULL CHECK (done IN (0, 1))
	);`
	_, err = db.Exec(query)
	if err != nil {
		log.Fatal(err)
	}
}

// Функция для добавления новой задачи в базу данных
func addTask(title, description string) (int64, error) {
	query := `INSERT INTO tasks (title, description, done) VALUES (?, ?, ?)`
	result, err := db.Exec(query, title, description, false)
	if err != nil {
		return 0, err
	}
	id, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}
	return id, nil
}

// Функция для получения всех задач
func getTasks() ([]Task, error) {
	rows, err := db.Query("SELECT id, title, description, done FROM tasks")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var tasks []Task
	for rows.Next() {
		var task Task
		if err := rows.Scan(&task.ID, &task.Title, &task.Description, &task.Done); err != nil {
			return nil, err
		}
		tasks = append(tasks, task)
	}

	return tasks, nil
}

// Функция для получения одной задачи по ID
func getTaskByID(id int) (Task, error) {
	var task Task
	query := "SELECT id, title, description, done FROM tasks WHERE id = ?"
	row := db.QueryRow(query, id)
	err := row.Scan(&task.ID, &task.Title, &task.Description, &task.Done)
	if err != nil {
		return Task{}, err
	}
	return task, nil
}

// Функция для обновления задачи
func updateTask(id int, title, description string, done bool) error {
	query := `UPDATE tasks SET title = ?, description = ?, done = ? WHERE id = ?`
	_, err := db.Exec(query, title, description, done, id)
	return err
}

// Функция для удаления задачи
func deleteTask(id int) error {
	query := `DELETE FROM tasks WHERE id = ?`
	_, err := db.Exec(query, id)
	return err
}

4. Модели данных (models.go)

В этом файле будет храниться структура для задачи.

goКопировать кодpackage main

// Структура для задачи
type Task struct {
	ID          int    `json:"id"`
	Title       string `json:"title"`
	Description string `json:"description"`
	Done        bool   `json:"done"`
}

5. Основной файл программы (main.go)

В этом файле будет реализован HTTP-сервер с использованием Gin, который будет обрабатывать запросы API.

goКопировать кодpackage main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

func main() {
	// Инициализация базы данных
	initDB()
	defer db.Close()

	// Создаем новый роутер Gin
	r := gin.Default()

	// Роуты API
	r.GET("/tasks", getAllTasks)
	r.GET("/tasks/:id", getTaskByID)
	r.POST("/tasks", createTask)
	r.PUT("/tasks/:id", updateTask)
	r.DELETE("/tasks/:id", deleteTask)

	// Запуск сервера
	r.Run(":8080")
}

// Получение всех задач
func getAllTasks(c *gin.Context) {
	tasks, err := getTasks()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, tasks)
}

// Получение задачи по ID
func getTaskByID(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	task, err := getTaskByID(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
		return
	}

	c.JSON(http.StatusOK, task)
}

// Создание новой задачи
func createTask(c *gin.Context) {
	var newTask Task
	if err := c.ShouldBindJSON(&newTask); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Добавляем задачу в базу данных
	id, err := addTask(newTask.Title, newTask.Description)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	newTask.ID = int(id)
	c.JSON(http.StatusCreated, newTask)
}

// Обновление существующей задачи
func updateTask(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	var updatedTask Task
	if err := c.ShouldBindJSON(&updatedTask); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	err = updateTask(id, updatedTask.Title, updatedTask.Description, updatedTask.Done)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
		return
	}

	updatedTask.ID = id
	c.JSON(http.StatusOK, updatedTask)
}

// Удаление задачи
func deleteTask(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	err = deleteTask(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
		return
	}

	c.JSON(http.StatusNoContent, gin.H{})
}

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

После того как мы создали программу, можем её запустить. Выполните команду:

bashКопировать кодgo run main.go

Теперь сервер будет работать на порту 8080. Вы можете использовать Postman или любой другой HTTP-клиент, чтобы взаимодействовать с API:

Примеры запросов:

  • GET /tasks — Получить все задачи.
  • GET /tasks/{id} — Получить задачу по ID.
  • POST /tasks — Создать новую задачу.
    • Тело запроса: { "title": "Task 1", "description": "Description of Task 1" }
  • PUT /tasks/{id} — Обновить задачу.
    • Тело запроса: { "title": "Updated Task", "description": "Updated description", "done": true }
  • DELETE /tasks/{id} — Удалить задачу.

Мы создали веб-приложение с API для управления задачами с использованием Go и Gin. В этом примере мы использовали SQLite для хранения данных, реализовали RESTful API для взаимодействия с данными и добавили основные CRUD-операции для задач.

Это приложение можно расширять, добавляя аутентификацию, более сложную логику обработки данных или фронтенд для работы с пользователем через веб-интерфейс.

Заключение

Go — это язык, который сочетает в себе простоту, высокую производительность и удобство работы с многозадачностью. Он идеально подходит для создания высоконагруженных систем, веб-сервисов, микросервисной архитектуры и многого другого.

В этой статье мы рассмотрели несколько примеров программ на Go, начиная с простых вводных программ и заканчивая созданием HTTP-сервера и использованием горутин. Благодаря своей простоте и возможностям Go стал популярным инструментом для разработки масштабируемых и производительных приложений.

+1
1
+1
2
+1
0
+1
0
+1
1

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *