Практика 5. Массивы и базовая работа со slices
Цель
Научиться создавать массивы и slices, обращаться к элементам, использовать
границы среза, len, range, make и базовый append, а также понимать
различие между копированием массива и общим хранилищем slices.
Общие требования
- создайте модуль
example.com/practice-05; - перед обращением по вычисляемому индексу проверяйте границы;
- функции обработки данных возвращают результат и не печатают его;
- все примеры должны работать на Linux, macOS и Windows;
- выполните
go fmt ./...,go test ./...,go vet ./....
A. Разминка
Задание 1. Массив недели
Создайте массив [7]string с названиями дней недели. Выведите:
- весь массив;
- первый и последний день;
- длину;
- каждый день с номером от 1 до 7.
Используйте range для обхода.
Задание 2. Zero values массива
Объявите:
var measurements [5]float64Выведите массив до и после заполнения трёх элементов. Объясните, почему остальные элементы равны нулю.
Задание 3. Копирование массива
first := [3]int{10, 20, 30}second := firstsecond[0] = 999Выведите оба массива. Объясните, почему изменение second не изменило first.
Создайте функцию:
func changeArray(values [3]int) [3]intОна меняет первый элемент копии и возвращает новый массив.
Задание 4. Первый slice
Создайте:
languages := []string{"Go", "Python", "Swift", "Java", "C#"}Получите и выведите:
- первые два элемента;
- последние три;
- элементы с индексами 1–3;
- весь slice через
[:].
Для каждого результата выведите len и cap.
B. Основные задания
Задание 5. Сумма, минимум и максимум
Реализуйте:
func sum(values []int) intfunc minMax(values []int) (minimum int, maximum int, ok bool)Для пустого slice minMax возвращает 0, 0, false. Для непустого нельзя
инициализировать минимум произвольным большим числом: используйте первый элемент.
Проверьте:
- положительные числа;
- отрицательные числа;
- один элемент;
- пустой slice.
Задание 6. Поиск элемента
Напишите:
func indexOf(values []string, target string) intФункция возвращает индекс первого совпадения или -1. Сравнение регистрозависимое.
Дополнительный вариант:
func indexOfFold(values []string, target string) intИспользуйте strings.EqualFold для поиска без учёта регистра.
Задание 7. Разворот
Реализуйте два варианта:
func reversed(values []int) []intfunc reverseInPlace(values []int)reversedвозвращает новый slice и не изменяет исходный;reverseInPlaceизменяет переданный slice.
Покажите разницу в main.
Задание 8. Фильтрация
Напишите:
func validScores(scores []int) []intОставьте только значения от 0 до 100. Результат должен быть новым slice, а исходные данные — остаться без изменений.
Предварительно выделите вместимость результата:
result := make([]int, 0, len(scores))Задание 9. Матрица
Создайте таблицу 3×4 как [][]int, заполните её числами от 1 до 12 и выведите
по строкам.
Затем вычислите:
- сумму каждой строки;
- сумму каждого столбца;
- сумму всех элементов.
Не предполагайте длину строки без проверки, если разрешите строки разной длины.
C. Проект «Список задач»
В этой работе названия задач хранятся в slice:
tasks := []string{ "Подготовить отчёт", "Проверить почту", "Исправить ошибку",}Реализуйте функции:
func addTask(tasks []string, title string) ([]string, bool)func findTask(tasks []string, title string) intfunc printTasks(tasks []string)Требования:
addTaskудаляет пробелы по краям черезstrings.TrimSpace;- пустое название не добавляется;
- дубликат без учёта регистра не добавляется;
- функция возвращает новый slice и признак успеха;
findTaskищет без учёта регистра;- нумерация при выводе начинается с 1;
- пустой список выводится как
Список задач пуст.
Сценарий:
- выведите начальный список;
- добавьте корректную задачу;
- попробуйте добавить пустое название;
- попробуйте добавить дубликат в другом регистре;
- найдите существующую задачу;
- найдите отсутствующую задачу;
- выведите итоговый список.
Пример:
1. Подготовить отчёт2. Проверить почту3. Исправить ошибку
Добавлено: Обновить документациюНе добавлено: пустое названиеНе добавлено: задача уже существует
Итоговый список:1. Подготовить отчёт2. Проверить почту3. Исправить ошибку4. Обновить документациюВажно: addTask должна возвращать результат append, а вызывающая сторона —
присваивать его обратно:
tasks, added = addTask(tasks, title)Дополнительные задания
Сдвиг влево
Напишите функцию, возвращающую новый slice, циклически сдвинутый на один элемент:
[1 2 3 4] → [2 3 4 1]Пустой slice и slice из одного элемента должны обрабатываться корректно.
Удаление повторов
Без использования map создайте функцию, сохраняющую только первое появление каждой строки. Сравнивайте строки без учёта регистра. Оцените сложность решения.
Критерии оценивания
| Критерий | Баллы |
|---|---|
| Массивы и понимание копирования | 0–3 |
Срезы, len, cap, границы | 0–3 |
| Функции поиска и статистики | 0–3 |
| Фильтрация и независимый результат | 0–3 |
| Проект «Список задач» | 0–4 |
| Максимум | 16 |
Вопросы для защиты
- Почему длина массива входит в его тип?
- Что происходит при присваивании массива?
- Чем литерал массива отличается от литерала slice?
- Что означают левая и правая границы среза?
- Чем
lenотличается отcap? - Почему результат
appendнужно присваивать? - Как изменить элементы slice через
range? - Почему
minMaxдолжен отдельно обрабатывать пустой slice?