Лабораторная работа №1 Тема: Настройка среды разработки (Environment Setup) и создание первого консольного приложения на GoLang.

Лабораторная работа №1
(Если нет админских прав в аудитории можно временно воспользоваться песочницей
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.”

3. Проверка:

    ◦ Нажмите 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.




Автор: к.п.н., Румянцев Сергей Александрович, доцент Финансового университета при Правительстве РФ; доцент ОЧУВО Международного инновационного университета; Консалтинг, управление разработкой ПО; системный и бизнес анализ; менеджмент; аналитиз данных; управление ИТ. Телефон для связи +79269444818 (мессенджеры)   Короткая ссылка:
Лабораторная работа №1
(Если нет админских прав в аудитории можно временно воспользоваться песочницей
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.”

3. Проверка:

    ◦ Нажмите 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.




https://webprogr.ru/~nz3d9
Короткая ссылка на новость:https://webprogr.ru/~nz3d9


Последние новости

Лабораторная работа №1 Тема: Настройка среды разработки (Environment Setup) и создание первого консольного приложения на GoLang.

Лабораторная работа №1
(Если нет админских прав в аудитории можно временно воспользоваться песочницей
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.”

3. Проверка:

    ◦ Нажмите 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.




Рейтинг@Mail.ru