(Если нет админских прав в аудитории можно временно воспользоваться песочницей
1) https://www.programiz.com/golang/online-compiler/
с возможностью ввода
2) www.codechef.com/go-online-compiler
3) или запасной вариант без возможности ввода
https://go.dev/play/ , пункты установки и подключения тогда на самостоятельное освоение вне аудитории. Если пользуетесь песочницей, то пропускаете этапы установки ПО и запуска команд)
Тема: Настройка среды разработки (Environment Setup) и создание первого консольного приложения на GoLang.
консольного приложения на GoLang.
Цель работы: Реализация компетенции ПКН-2: Умение настраивать среды разработки под свои нужды, использовать плагины, настройки компиляции и запуска. Научиться создавать простейшие алгоритмы и программы.
Оборудование: Компьютер под управлением ОС Windows.
Ход работы
Часть 1: Установка компилятора Go
1. Скачивание:
◦ Перейдите на официальный сайт
go.dev/dl.◦ Выберите версию для Microsoft Windows (файл с расширением
.msi).2. Установка:
◦ Запустите скачанный установщик. Следуйте инструкциям мастера установки (Next -> Accept -> Install).
◦ По умолчанию Go устанавливается в
C:\Program Files\Go.◦ Важно: Убедитесь, что галочка "Add Go to PATH" установлена (обычно включена по умолчанию). Это позволит запускать команды Go из любой консоли.
Примечание:
-
По поводу фразы «галочка Add Go to PATH»: корректнее “установщик на Windows обычно настраивает окружение, проверяем командой
go version”. То есть “После установки откройте cmd/PowerShell и выполнитеgo version. Если команда не находится — проверьте PATH.”
◦ Нажмите
Win + R, введите cmd и нажмите Enter.◦ В консоли введите команду:
go version◦ Если установка прошла успешно, вы увидите вывод, например:
go version go1.22.0 windows/amd64.Часть 2: Выбор и установка IDE (Вариант А: VS Code)
В соответствии с требованиями программы, студент должен знать основные функции IDE.
1. Установка VS Code:
◦ Скачайте установочный файл с
code.visualstudio.com и установите его.2. Настройка под Go:
◦ Откройте VS Code.
◦ Перейдите в раздел расширений (квадратная иконка слева или
Ctrl+Shift+X).◦ Введите в поиске "Go".
◦ Выберите официальное расширение от Go Team at Google и нажмите Install.
3. Обновление инструментов:
◦ После установки расширения откройте палитру команд (
Ctrl+Shift+P).◦ Введите:
Go: Install/Update Tools.◦ Выберите все предложенные пункты (gopls, dlv, staticcheck и др.) и нажмите OK. Это обеспечит автодополнение, форматирование и отладку кода.
Часть 3: Выбор и установка IDE (Вариант Б: Cursor)
Cursor — это современный форк VS Code со встроенным ИИ, что соответствует тренду использования современных технологий программирования.
1. Установка Cursor:
◦ Перейдите на сайт cursor.com
cursor.sh )◦ Скачайте инсталлятор для Windows и запустите его.
2. Первичная настройка:
◦ При первом запуске Cursor предложит импортировать настройки и расширения из уже установленного VS Code. Выберите "Import", чтобы автоматически перенести установленное расширение Go и настройки тем.
◦ Если импорт пропущен, установите расширение Go так же, как в Части 2 (интерфейс идентичен).
3. Особенности:
◦ Нажмите
Ctrl+K в редакторе, чтобы вызвать AI-ассистента для генерации кода.Часть 4: Создание первого консольного приложения
В соответствии с заданиями курса, вы должны уметь организовывать кодовую базу и структурировать проект.
1. Создание рабочей директории:
◦ Создайте папку для ваших проектов, например
C:\Projects\GoCourse.◦ Внутри создайте папку для первой работы:
Lab1.2. Инициализация модуля:
◦ Откройте эту папку в выбранной IDE (File -> Open Folder).
◦ Откройте терминал внутри IDE (
Ctrl + ~ или Terminal -> New Terminal).◦ Введите команду для инициализации модуля (задает имя проекта):
go mod init lab1◦ Появится файл
go.mod — он управляет зависимостями.3. Написание кода:
◦ Создайте файл
main.go.◦ Введите следующий код (базовая структура консольного приложения):
package main // Объявление пакета. Точка входа всегда package main
import (
"fmt" // Импорт пакета для форматированного ввода/вывода
"time"
)
// Функция main - точка входа в программу
func main() {
// Вывод текста в консоль
fmt.Println("Лабораторная работа №1: GoLang Environment")
fmt.Println("Текущее время:", time.Now().Format(time.RFC1123))
// Пример простейшей интерактивности (консольный ввод)
fmt.Print("Введите ваше имя: ")
var name string
fmt.Scanln(&name)
fmt.Printf("Привет, %s! Среда настроена успешно.\n", name)
}
Часть 5: Запуск и Компиляция
1. Прямой запуск (режим интерпретации):
◦ В терминале введите:
go run main.go◦ Программа скомпилируется во временную папку и запустится. Используется для быстрой проверки.
Примечание: На самом деле Go не интерпретируется;
go run компилирует во временный бинарник и запускает.2. Компиляция (Build):
◦ Введите:
go build◦ В папке проекта появится исполняемый файл
lab1.exe.◦ Запустите его через терминал:
.\lab1.exeЗадание для самостоятельной работы (на основе принципов):
Модифицируйте программу так, чтобы она:
1. Запрашивала у пользователя два числа (используя
fmt.Scan).2. Выводила результат их сложения, вычитания и умножения.
3. Усложненный уровень: Обработайте ошибку ввода (если пользователь ввел буквы вместо цифр), используя конструкцию
if err != nil.Часть 6: Расширенная работа с вводом/выводом (I/O)
В предыдущей части мы использовали
fmt.Scanln, который считывает только до первого пробела. Для создания полноценных консольных утилит (CLI) часто требуется считывать строки целиком.1. Модификация кода: Откройте файл
main.go и замените содержимое на следующий код, использующий пакет bufio для буферизированного ввода:package main
import (
"bufio" // Пакет для буферизированного ввода-вывода
"fmt"
"os" // Пакет для взаимодействия с операционной системой
"strings" // Пакет для работы со строками
)
func main() {
// Создаем ридер для чтения из стандартного ввода (консоли)
reader := bufio.NewReader(os.Stdin)
fmt.Print("Введите ваше полное имя и фамилию: ")
// Читаем строку до символа переноса строки '\n'
input, _ := reader.ReadString('\n')
// Удаляем лишние пробелы и символ переноса строки из полученных данных
name := strings.TrimSpace(input)
fmt.Printf("Привет, %s! Добро пожаловать в мир Go.\n", name)
}
2. Запуск: Проверьте работу программы через
go run main.go. Теперь вы можете вводить имя с пробелами (например, "Иван Иванов").Часть 7: Основы синтаксиса и управляющие конструкции
Реализуем простейшую логику ветвления, характерную для консольных утилит.
1. Добавление логики: Дополните функцию
main следующим кодом (после приветствия): fmt.Println("Выберите действие:")
fmt.Println("1. Узнать текущее время")
fmt.Println("2. Выход")
fmt.Print("Ваш выбор: ")
// Для считывания одного числа удобно использовать Scan
var choice int
fmt.Scan(&choice)
// Управляющая конструкция if-else (скобки вокруг условия не нужны)
if choice == 1 {
// Используем пакет time (нужно добавить "time" в import)
import "time" // Вставьте это в блок import выше
fmt.Println("Сейчас:", time.Now().Format(time.RFC1123))
} else if choice == 2 {
fmt.Println("До свидания!")
os.Exit(0) // Завершение программы
} else {
fmt.Println("Неверный выбор.")
}
Часть 8: Кросс-компиляция (Сборка под разные ОС) (НЕОБЯЗАТЕЛЬНО - ПО ЖЕЛАНИЮ)
Одной из киллер-фич Go является возможность скомпилировать
.exe файл для Windows, бинарник для Linux или macOS, находясь на одной машине, без установки виртуальных машин.1. Сборка для Windows (текущая ОС): В терминале выполните:
2. Это создаст стандартный исполняемый файл.
3. Сборка для Linux (из Windows): В PowerShell (терминал VS Code) выполните команды для установки переменных окружения
GOOS (операционная система) и GOARCH (архитектура процессора):4. Результат: В папке появится файл
myapp-linux (без расширения), который можно запустить на сервере Ubuntu/Debian.5. Сборка для macOS (из Windows):
6. (Используйте amd64 для старых маков на Intel и arm64 для маков на чипах M1/M2/M3).
7. Возврат настроек: Не забудьте сбросить переменные, чтобы снова компилировать под Windows:
Часть 9: Работа с Git в VS Code / Cursor (НЕОБЯЗАТЕЛЬНО)
Поскольку курс подразумевает командную работу, настроим контроль версий.
1. Инициализация:
◦ В терминале IDE введите:
git init◦ Вы увидите сообщение
Initialized empty Git repository.2. Игнорирование файлов:
◦ Создайте файл
.gitignore в корне проекта.◦ Добавьте в него строку
*.exe и myapp-*, чтобы не засорять репозиторий скомпилированными файлами.3. Первый коммит:
◦ В меню слева перейдите на вкладку Source Control (иконка ветки).
◦ Нажмите Stage All Changes (плюсик).
◦ Введите сообщение (например, "Initial commit: Lab 1 finished") и нажмите Commit.
Часть 10: Переменные и математические операции
В Go строгая статическая типизация. Студентам нужно освоить два способа объявления переменных: полный (через
var) и краткий (через :=), который работает только внутри функцийЗадание: Модифицируйте код, чтобы программа спрашивала год рождения пользователя и рассчитывала его возраст.
1. В функции
main добавьте объявление переменных для текущего года и года рождения.2. Используйте пакет
strconv для преобразования строки (ввод пользователя) в число, так как bufio возвращает строку.Код для вставки:
import (
"bufio"
"fmt"
"os"
"strconv" // Пакет для конвертации строк в числа
"strings"
"time"
)
func main() {
// ... (код приветствия из предыдущих частей) ...
reader := bufio.NewReader(os.Stdin)
// 1. Полное объявление переменной
var birthYearString string
fmt.Print("Введите ваш год рождения: ")
birthYearString, _ = reader.ReadString('\n')
// Удаляем пробелы и символ новой строки
birthYearString = strings.TrimSpace(birthYearString)
// 2. Обработка ошибок при конвертации (важная часть Go)
// Atoi = ASCII to Integer. Возвращает число и ошибку
birthYear, err := strconv.Atoi(birthYearString)
if err != nil {
fmt.Println("Ошибка: вы ввели не число!")
} else {
// 3. Краткое объявление переменной (только внутри функций)
currentYear := time.Now().Year()
age := currentYear - birthYear
// %d - плейсхолдер для десятичных чисел
fmt.Printf("Вам сейчас (или исполнится в этом году): %d лет.\n", age)
}
}
Часть 11: Управляющие конструкции (Switch и If)
Go имеет свои особенности в условиях:
if не требует круглых скобок, а switch не требует break (он не "проваливается" в следующий кейс по умолчанию)Задание: Реализуйте простое интерактивное меню, используя
switch.Код для вставки (продолжение main):
fmt.Println("-------------")
fmt.Println("МЕНЮ:")
fmt.Println("1. Показать текущее время")
fmt.Println("2. Показать информацию о системе")
fmt.Println("3. Выход")
fmt.Print("Выберите пункт: ")
choiceStr, _ := reader.ReadString('\n')
choice := strings.TrimSpace(choiceStr)
// Switch в Go работает быстрее цепочки if-else и выглядит чище
switch choice {
case "1":
fmt.Println("Время:", time.Now().Format("15:04:05"))
case "2":
// GOOS и GOARCH - константы из пакета runtime
// Требуется добавить "runtime" в import
fmt.Println("Вы используете ОС Windows (или другую)")
case "3":
fmt.Println("Выход из программы...")
os.Exit(0)
default:
fmt.Println("Неверная команда.")
}
Примечание: Синтаксис switch без break; отсутствие скобок в if
Часть 12: Массивы, Слайсы (Slices) и Циклы
Это критически важная тема. В Go редко используют массивы (фиксированный размер), чаще — слайсы (динамический размер). Также в Go есть только один вид цикла —
for
Задание: Создайте список задач (TODO list). Попросите пользователя ввести 3 задачи, сохраните их в слайс, а затем выведите список с нумерацией.
Код для вставки:
// Объявление слайса (динамического массива) строк
// Отличие от массива: в квадратных скобках [] ничего нет
var todoList []string
fmt.Println("\n--- Создание списка задач ---")
// Классический цикл for (как в C/Java, но без скобок)
for i := 0; i < 3; i++ {
fmt.Printf("Введите задачу №%d: ", i+1)
task, _ := reader.ReadString('\n')
task = strings.TrimSpace(task)
// В Go добавление в слайс делается через функцию append
// Она возвращает новый, расширенный слайс
todoList = append(todoList, task)
}
fmt.Println("\nВаш список задач:")
// Цикл for-range (аналог foreach в других языках)
// i - индекс, task - значение элемента (копия)
for i, task := range todoList {
fmt.Printf("%d. %s\n", i+1, task)
}
Полный код
main.go для Лабораторной №1 (Сводный)вот как должен выглядеть итоговый файл, объединяющий все части (ввод/вывод, переменные, ветвления, циклы и слайсы).
package main
import (
"bufio"
"fmt"
"os"
"runtime"
"strconv"
"strings"
"time"
)
func main() {
// --- ЧАСТЬ 1: Ввод-вывод и строки ---
reader := bufio.NewReader(os.Stdin)
fmt.Print("Введите ваше имя: ")
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
fmt.Printf("Привет, %s! Добро пожаловать в Go.\n", name)
// --- ЧАСТЬ 2: Переменные и конвертация типов ---
fmt.Print("Введите год вашего рождения: ")
yearStr, _ := reader.ReadString('\n')
yearStr = strings.TrimSpace(yearStr)
birthYear, err := strconv.Atoi(yearStr)
if err != nil {
fmt.Println("Ошибка: введено не число. Возраст рассчитать невозможно.")
} else {
age := time.Now().Year() - birthYear
fmt.Printf("Ваш возраст: %d\n", age)
}
// --- ЧАСТЬ 3: Слайсы и Циклы ---
fmt.Println("\nДавайте составим список из 3-х дел.")
var tasks []string // Слайс (динамический массив)
for i := 0; i < 3; i++ {
fmt.Printf("Введите дело %d: ", i+1)
task, _ := reader.ReadString('\n')
tasks = append(tasks, strings.TrimSpace(task)) // append добавляет элемент
}
// --- ЧАСТЬ 4: Switch и вывод данных ---
for { // Бесконечный цикл, пока не вызовем break или os.Exit
fmt.Println("\n--- МЕНЮ ---")
fmt.Println("1. Показать список дел")
fmt.Println("2. Показать информацию о системе")
fmt.Println("3. Выход")
fmt.Print("Ваш выбор: ")
choice, _ := reader.ReadString('\n')
choice = strings.TrimSpace(choice)
switch choice {
case "1":
fmt.Println("Ваши задачи:")
// range возвращает индекс и копию значения
for i, t := range tasks {
fmt.Printf("%d. %s\n", i+1, t)
}
case "2":
fmt.Printf("OS: %s\nArch: %s\nGo Version: %s\n",
runtime.GOOS, runtime.GOARCH, runtime.Version())
case "3":
fmt.Println("До свидания!")
os.Exit(0) // Завершение программы
default:
fmt.Println("Неизвестная команда, попробуйте снова.")
}
}
}
Задания для защиты работы (контрольные вопросы):
1. Почему при объявлении
var tasks []string мы не указываем размер в квадратных скобках? (Ответ: это слайс, а не массив, он динамический)2. Зачем мы используем
strings.TrimSpace после чтения ввода? (Ответ: ReadString считывает символ Enter (\n), его нужно удалить)3. Как выйти из бесконечного цикла
for {}? (Ответ: break или os.Exit).
Часть 9: Аргументы командной строки (Flags)
Профессиональные консольные утилиты часто запускаются с параметрами. Go имеет мощный встроенный пакет
flag для этого.Задание: Модифицируйте программу так, чтобы она могла принимать имя пользователя и год рождения не через опрос, а сразу при запуске из консоли.
Код для вставки (начало функции main):
import (
"flag" // Пакет для парсинга аргументов командной строки
// ... остальные импорты
)
func main() {
// 1. Объявляем флаги.
// "n" - имя флага (-n), "Guest" - значение по умолчанию, строка - описание
namePtr := flag.String("n", "", "Ваше имя")
yearPtr := flag.Int("y", 0, "Ваш год рождения")
// 2. Парсим аргументы (обязательно вызвать перед использованием!)
flag.Parse()
var name string
var birthYear int
// Проверяем: если флаги не переданы (остались значения по умолчанию/пустые),
// включаем интерактивный режим (тот, что писали в прошлых частях)
if *namePtr == "" {
fmt.Println("Запуск в интерактивном режиме (попробуйте запустить с флагом -h)")
// ... (сюда переносим код с bufio.NewReader из предыдущих частей)
} else {
// Если флаги переданы, используем их
name = *namePtr
birthYear = *yearPtr
fmt.Printf("Привет, %s! (Данные получены через флаги)\n", name)
}
// ... (далее логика расчета возраста)
}
Как проверять: Студент должен запустить программу в терминале командой:
go run main.go -n "Алексей" -y 1995--------------------------------------------------------------------------------
Часть 13: Механизм Defer (Отложенный вызов) (ЖЕЛАТЕЛЬНО)
Go имеет уникальный оператор
defer, который гарантирует выполнение функции перед выходом из программы (даже если произошла ошибка). Это аналог блоков finally в других языках, но более гибкий.Задание: Добавьте в самое начало функции
main (сразу после flag.Parse()) сообщение о завершении работы, которое появится только в самом конце.Код:
// ... после flag.Parse()
// Этот код выполнится в самом конце функции main, перед выходом
defer fmt.Println("\n--- Программа завершила работу корректно ---")
fmt.Println("Программа запущена...")
Итоговый (обновленный) код
main.goТеперь это выглядит как полноценная CLI-утилита.package main
import (
"bufio"
"flag" // [2]
"fmt"
"os"
"strconv"
"strings"
"time"
)
func main() {
// --- ЧАСТЬ 9: Флаги (CLI Arguments) ---
// Утилита может принимать параметры: myapp.exe -name="Ivan" -year=2000
nameFlag := flag.String("name", "", "Имя пользователя")
yearFlag := flag.Int("year", 0, "Год рождения")
flag.Parse() // [2]
// --- ЧАСТЬ 10: Defer ---
// Сообщение выведется в самом конце, перед закрытием программы [1]
defer fmt.Println("\n[LOG] Работа приложения завершена.")
var name string
var birthYear int
var err error
// Логика: Если флагов нет, спрашиваем интерактивно. Если есть - используем их.
if *nameFlag == "" {
fmt.Println("Режим интерактивного ввода (используйте -h для справки по флагам).")
// --- ЧАСТЬ 1: Ввод-вывод ---
reader := bufio.NewReader(os.Stdin) // [4]
fmt.Print("Введите ваше имя: ")
nameInput, _ := reader.ReadString('\n')
name = strings.TrimSpace(nameInput)
fmt.Print("Введите год рождения: ")
yearInput, _ := reader.ReadString('\n')
yearInput = strings.TrimSpace(yearInput)
// --- ЧАСТЬ 2: Конвертация ---
birthYear, err = strconv.Atoi(yearInput)
if err != nil {
fmt.Println("Ошибка: введен некорректный год.")
return // Досрочный выход
}
} else {
name = *nameFlag
birthYear = *yearFlag
}
// Основная логика
age := time.Now().Year() - birthYear
fmt.Printf("\nПривет, %s! Ваш возраст: %d\n", name, age)
// --- ЧАСТЬ 3: Слайсы и Циклы ---
if age < 100 { // Простое условие
fmt.Println("Список задач на сегодня:")
tasks := []string{"Изучить Go", "Настроить VS Code", "Запушить в Git"} // Слайс [5]
// Цикл range [6]
for i, t := range tasks {
fmt.Printf("%d. %s\n", i+1, t)
}
}
}
Рекомендация к финальной защите (Контроль)
Для защиты работы студенты должны уметь объяснить:
1. Разницу между
go run и go build.2. Зачем нужен
defer и в каком порядке он выполняется.3. Как просмотреть справку по своей программе (автоматически генерируется флагами:
go run main.go -h).Лабораторная 1 покрывает компетенции ПКН-2 и ПКН-3.

