Зарегистрируйтесь, чтобы продолжить обучение

Массивы Основы Go

Массив — это структура данных, содержащая фиксированное количество элементов одного типа. Это поведение похоже на массивы в языках вроде C или Pascal, где размер известен во время компиляции и не может изменяться после создания.

Объявление массива

Тип массива составной, он включает в себя информацию о том, что это массив и о том, какой тип хранится внутри него.

var nums [5]int
  • Тип: массив из пяти int.
  • Все значения инициализируются нулями (0 для int).

Можно использовать короткую форму:

// Скобки обязательны
nums := [5]int{}

Скобки {} здесь обязательны, потому что они указывают на создание литерала массива. Даже если значения по умолчанию, Go требует явного указания структуры.

Если указать меньше значений, оставшиеся элементы будут инициализированы нулями.

nums := [4]int{1, 2}

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

Инициализация значениями

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

nums := [3]int{1, 2, 3}

Если указано больше элементов, чем заданная длина — будет ошибка компиляции.

nums := [1]int{1, 2} // ошибка: index 1 out of bounds [0:1]

Можно также задать длину неявно, используя .... Она посчитается автоматически, на основе переданных значений во время инициализации:

nums := [...]int{10, 20, 30} // длина будет равна 3

Доступ к элементам и их изменение

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

nums := [3]int{1, 2, 3}

fmt.Println(nums[1]) // => 2

nums[2] = 33

fmt.Println(nums) // => [1 2 33]

Обращение за пределы массива вызывает ошибку компиляции:

words := [2]string{}
words[2] // ошибка: index 2 out of bounds [0:2]

Длина массива

Go предоставляет встроенную функцию len() для получения длины массива. Эта длина известна во время компиляции и не меняется.

fmt.Println(len([5]int{1, 2, 3})) // => 5
fmt.Println(len([10]int{}))       // => 10

Передача и возврат из функции

Массивы передаются и возвращаются по значению, то есть копируются. Даже если изменить массив внутри функции, оригинал не изменится.

func modify(items [3]int) [3]int {
    items[0] = 100
    return items
}

func main() {
    a := [3]int{1, 2, 3}
    b := modify(a)
    // оригинал не изменился
    fmt.Println(a) // => [1 2 3]

    // результат функции
    fmt.Println(b) // [100 2 3]
}

Чтобы изменить массив "на месте", обычно передают указатель на массив (*[3]int) или используют срез.

Пример: Переворот строки

Посмотрим на комплексный пример использования массива вместе с циклом. Ниже происходит переворот строки, заранее разбитой на массив рун.

func reverse(text [5]rune) [5]rune {
    var result [5]rune
    for i := 0; i < len(text); i++ {
        result[i] = text[len(text) - 1 - i]
    }
    return result
}

func main() {
    text := [5]rune{'п', 'р', 'и', 'в', 'е'}
    reversed := reverse(text)
    fmt.Println(string(reversed[:])) // => "евирп"
}

Применение массивов на практике

Фиксированная длина делает массивы неудобными для большинства задач, где размер данных заранее неизвестен. Например, если вы читаете данные из файла, получаете значения из сети или формируете список на основе пользовательского ввода — вы не можете заранее указать точное количество элементов. А так как длина массива в Go жёстко зашита в его тип, менять её динамически невозможно. Поэтому на практике почти всегда используют срезы (slices) — они позволяют работать с коллекциями переменной длины.


Дополнительные материалы

  1. Array types
  2. Effective Go — Array types

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff