Тип slice

Тип slice в Go представляет собой динамический массив, который может изменять свой размер во время выполнения программы. В отличие от массивов, размер слайса не фиксирован и может увеличиваться или уменьшаться по мере необходимости. Слайс состоит из трех компонентов: указателя на базовый массив, длины (количество элементов) и емкости (максимальное количество элементов без перераспределения памяти).

Создание слайса

Создать слайс можно несколькими способами. Рассмотрим основные из них:

gopackage main

import "fmt"

func main() {
  // Создание пустого слайса
  var s1 []int
  fmt.Println(s1)

  // Создание слайса с начальными значениями
  s2 := []string{"a", "b", "c", "d", "e"}
  fmt.Println(s2)

  // Создание слайса с помощью make
  s3 := make([]int, 5, 10)
  fmt.Println(s3)
}

Результат выполнения кода:

go[]
[a b c d e]
[0 0 0 0 0]

В первом случае мы создаем пустой слайс, во втором - слайс с элементами, в третьем - слайс с длиной 5 и емкостью 10 через функцию make.

Длина и емкость слайса

Длина слайса - это количество элементов в нем, а емкость - максимальное количество элементов, которое может быть размещено без выделения новой памяти. Получить эти значения можно с помощью встроенных функций len и cap:

gopackage main

import "fmt"

func main() {
  s := []int{1, 2, 3, 4, 5}
  fmt.Printf("len: %d, cap: %d", len(s), cap(s))
}

Результат выполнения кода:

go"len: 5, cap: 5"

В этом примере длина и емкость слайса равны, так как мы создали его через литерал.

Добавление элементов

Для добавления элементов в слайс используется встроенная функция append. Она добавляет элементы в конец слайса и возвращает новый слайс:

gopackage main

import "fmt"

func main() {
  s := []int{1, 2, 3}
  s = append(s, 4, 5)
  fmt.Println(s)
}

Результат выполнения кода:

go[1 2 3 4 5]

Важно помнить, что функция append может выделить новую память, если емкости текущего слайса недостаточно для добавления элементов.

Создание среза из слайса

Слайс позволяет создавать новые слайсы на основе существующего. Для этого используется синтаксис с указанием диапазона индексов:

gopackage main

import "fmt"

func main() {
  s := []string{"a", "b", "c", "d", "e"}
  sub := s[1:4]
  fmt.Println(sub)
}

Результат выполнения кода:

go[b c d]

В этом примере мы создаем новый слайс sub, который содержит элементы с индекса 1 по 3 (индекс 4 не включается).

Изменение элементов

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

gopackage main

import "fmt"

func main() {
  s := []int{1, 2, 3, 4, 5}
  s[2] = 10
  fmt.Println(s)
}

Результат выполнения кода:

go[1 2 10 4 5]

Здесь мы изменяем третий элемент (индекс 2) слайса, заменяя его значение на 10.

Объединение слайсов

Для объединения двух слайсов используется функция append с оператором разворачивания ...:

gopackage main

import "fmt"

func main() {
  s1 := []int{1, 2, 3}
  s2 := []int{4, 5, 6}
  res := append(s1, s2...)
  fmt.Println(res)
}

Результат выполнения кода:

go[1 2 3 4 5 6]

Оператор ... разворачивает второй слайс, передавая его элементы как отдельные аргументы в функцию append.

Сравнение слайсов

Слайсы нельзя сравнивать напрямую с помощью оператора == (за исключением сравнения с nil). Для сравнения необходимо сравнивать элементы по отдельности:

gopackage main

import "fmt"

func main() {
  s1 := []int{1, 2, 3}
  s2 := []int{1, 2, 3}
  equal := true

  if len(s1) != len(s2) {
    equal = false
  } else {
    for i := range s1 {
      if s1[i] != s2[i] {
        equal = false
        break
      }
    }
  }

  fmt.Println(equal)
}

Результат выполнения кода:

gotrue

В этом примере мы сравниваем два слайса, проверяя каждый элемент по отдельности.

Смотрите также

  • тип array,
    который представляет собой массив с фиксированным размером
  • тип map,
    который представляет собой коллекцию пар ключ-значение
  • функцию make,
    которая используется для создания слайсов, карт и каналов
  • тип string,
    который представляет собой неизменяемую строку