Срез массива в Golang

После чтения данного урока вы сможете:

  1. В случае необходимости использовать срез массива;
  2. Упорядочить срезы в алфавитном порядке через стандартную библиотеку.

Содержание статьи

Планеты нашей Солнечной системы принято классифицировать на планеты земной группы, газовые гиганты и ледяные гиганты. Ниже дается схема. Пока что можем сфокусироваться на земной группе, отрезав первые четыре элементы массива planets через planets[0:4]. Срез не изменяет массив planets. Он просто создает своеобразное окно, или вид внутрь массива. Данный вид называют срезом.

Форум Гоферов

Мы работаем над форумом для программистов на Golang. Очень нужны модераторы которые хотят помочь с ответами для новичков и помочь в развитии Go-сообщества.

Go на Форум

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК Go в Telegram

срезы массива go

Срез Солнечной системы

У вас есть какие-то коллекции? Они организованы в определенном порядке? К примеру, книги на полке могут быть рассортированы по фамилиям автора. Упорядочивание подобного рода помогает ориентироваться и быстро книги.

Таким же образом вы можете также использовать срезы к нулю как часть коллекции.

Срез массива в Golang

Срез выражается через наполовину открытый диапазон. В следующем примере planets[0:4] начинается с планеты с индексом 0, продолжается, но не включает планету с индексом 4.

Хотя terrestrial, gasGiants и iceGiants являются срезами, вы по-прежнему можете получать значение по индексу внутри срезов, как и внутри массивов:

Вы также можете разрезать массив, а потом полученный срез разрезать еще раз:

Срезы terrestrial, gasGiants, iceGiants, giants, gas и ice являются видами одного и того же массива planets. Присваивание нового значения к элементу среза меняет базовый массив planets. Изменение будет видно и в других срезах:

Вопросы для проверки:

  • Что получается в результате разреза массива?
  • При разрезе через planets[4:6] сколько элементов получится в конечном итоге?

Индексы для среза по умолчанию

При разрезе массива пропуск первого индекса равнозначен указанию начала массива, а пропуск последнего индекса — длине массива. Таким образом, разрез в Листинге 1 можно написать и так:

Обратите внимание, что индексы среза не могут быть отрицательными.

К чему приводит пропуск обоих индексов? Переменная allPlanets является срезом, который теперь содержит все восемь планет:

Срез строк в Golang

Синтаксис среза массива также можно использовать для строк:

Результатом среза строки является другая строка. Однако, присваивание нового значения neptune не изменит значения tune и наоборот:

Имейте в виду, что индексы учитывают количество байтов, но не рун:

Вопрос для проверки: 

Если бы Земля и Марс были единственными колонизированными планетами, как бы вы могли получить срез colonized от terrestrial?

Композитные литералы для срезов

Многие функции Go лучше оперируют со срезами, чем с массивами. Если вам нужен срез, что показывает каждый элемент базового массива, можно объявить массив, а затем сделать срез через [:]. Это делается следующим образом:

Разрез массива является одним из способов создания среза, однако вы также можете объявить срез напрямую. У среза строк тип []string, внутри квадратных скобок нет никакого значения. Это отличается от объявления массива, где всегда уточняется фиксированная длина или многоточие внутри квадратных скобок.

В следующем примере срез dwarfs инициализируется через уже знакомый синтаксис композитного литерала:

Базовый массив по-прежнему существует. Незаметно, Go сам объявляет массив из пяти элементов, а затем делает срез, что показывает все элементы.

Задание для проверки: 

Используйте специальный символ %T для сравнения типов dwarfArray и среза dwarfs.

Преимущества среза массива в Golang

Представьте, что существует способ преодолеть преграды пространства и времени, что позволяет объединять миры и путешествовать в мгновение ока? Использование стандартной библиотеки Go в совокупности с некоторой изобретательностью позволяет функции hyperspace из Листинга 4 модифицировать срез worlds, убрав отступы между мирами разных планет.

Оба worlds и planets являются срезами, и хотя worlds представляет собой копию, они оба указывают на один и тот же базовый массив.

Если бы hyperspace изменил точки начала или конца среза worlds, данные изменения не оказали бы никакого влияния на срез planets. Однако hyperspace может достигнуть базового массива, на который указывает worlds, и изменить его элементы. Данные изменения доступны другим срезам (видам) массива.

Срезы более изменчивые, нежели массивы и в других аспектах. У срезов есть длина, однако, в отличие от длины массивов, она не является частью типа. Вы можете передать срез любого размера функции hyperspace:

Массивы редко используются напрямую. Разработчики Go предпочитают срезы ввиду их гибкости, особенно при передачи аргументов функции.

Вопрос для проверки:

Просмотрите документацию Go, отыщите TrimSpace и Join. Какую функциональность они предоставляют?

Срезы с методами в Golang

В Go можно определить тип через базовый срез или массив. При наличии типа вы можете закрепить за ним метод. Способность Go объявлять методы типам доказывает их многогранность по сравнению с классами в других языках.

Пакет sort стандартной библиотеки объявляет тип StringSlice:

К StringSlice прикрепляется метод Sort:

Для упорядочивания планет в алфавитном порядке в следующем примере planets конвертируется в тип sort.StringSlice, а затем вызывается метод Sort:

В пакете sort есть вспомогательная функция Strings для конвертации типа и вызова метода Sort. Это значительно облегчает процесс:

Вопрос для проверки:

Что делает sort.StringSlice(planets)?

Заключение

  • Срез можно назвать окном, или видом в массив;
  • Ключевое слово range может итерировать через срезы;
  • Срезы разделяют одинаковую базовую информацию во время присваивания или передачи другим функциям;
  • Композитные литералы предоставляют удобные способы для инициализации срезов;
  • Вы можете прикрепить методы к срезам.

Итоговое задание для проверки:

Напишите программу для преобразования среза строки через добавление слова "Новый " перед названием планеты. Используйте программу для изменения названий планет Марс, Уран и Нептун.

В первой итерации может использоваться функция terraform, но в конечной реализации должен быть введен тип Planets с методом terraform, похожим на sort.StringSlice.