Массивы в Go является структурой фиксированный длины, которая содержит элементы одного типа.
Объявление массива
// массив можно объявить через var, например, массив из 5 элементов типа int, по умолчанию инициализируются нулями
var a [5]int
fmt.Println(a) // [0 0 0 0 0]
// также можно инициализировать массив при объявлении, например, массив из 3 элементов типа int
b := [3]int{1, 2, 3}
fmt.Println(b) // [1, 2, 3]
// Можно использовать краткую форму объявления массива, которая автоматически определит длину на этапе компиляции
c := [...]int{10, 20, 30}
fmt.Println(c) // [10 20 30]
Важно отметить, что массив в Go является значимым типом, а не ссылочным, и при объявлении выделяет фиксированный блок памяти, который используется для хранения всех его элементов.
В памяти массив из 5-и byte элементов будет выглядеть следующим образом:
Массив a: [5]byte{1, 2, 3, 4, 5}
Память:
+----+----+----+----+----+
| 1 | 2 | 3 | 4 | 5 |
+----+----+----+----+----+
Индексы:
0 1 2 3 4
Рассмотрим основные операции с массивами
Нумерация элементов массива начинается с 0
a := [5]byte{1, 2, 3, 4, 5}
// обращение к элементу массива
fmt.Println(a[0]) // 1
fmt.Println(a[4]) // 5
// если обратиться к элементу массива вне диапазона, то по сути мы попытаемся получить чужую область памяти, на практике это приведет к панике
fmt.Println(b[5]) // panic: index out of range
Для того, чтобы работать с массивами было удобно, в Go есть следующие функции:
a := [5]byte{1, 2, 3, 4, 5}
// Получить длину массива
len(a) // 5
//Получить вместимость массива
cap(a) // 5Так как массивы являются фиксированными по длине, то для них не поддерживается функция append.
Итерирование по элементам массива
package main
import "fmt"
func main() {
a := [4]int64{111, 222, 333, 444}
for i, v := range a {
fmt.Printf("index %d: value %d \n", i, v)
}
}
// Выведет
index 0: value 111
index 1: value 222
index 2: value 333
index 3: value 444 Во время итерации по массиву он также копируется, поэтому следующий код не будет менять данные массива внутри цикла:
package main
import "fmt"
func main() {
a := [4]int64{111, 222, 333, 444}
for i, v := range a {
a[3] = 777 // пытаемся изменить 3-ий элемент массива
fmt.Printf("index %d: value %d \n", i, v)
}
fmt.Println(a)
}
// Внутри цикла значения такие же как и при инициализации
// index 0: value 111
// index 1: value 222
// index 2: value 333
// index 3: value 444
// При этом исходный массив мы изменили
// [111 222 333 777]Копирование массивов
Прямого копирования массивов в Go нет, но при этом мы можем привести массив к срезу
package main
import "fmt"
func main() {
var src [3]int = [3]int{1, 2, 3}
var dst [3]int
// Приведение массивов к срезам
copy(dst[:], src[:])
fmt.Println("Исходный массив:", src) // Исходный массив: [1 2 3]
fmt.Println("Целевой массив:", dst) // Целевой массив: [1 2 3]
}Не будем останавилваться на различиях slice и array, так как этому будет посвящен следующий раздел.
Сравнение массивов
В предыдущих статьях мы обсуждали, что массивы можно сравнивать напрямую, если их элементы сравнимы. Для того, чтобы элементы были == все их значения должны быть равны.
package main
import "fmt"
func main() {
a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
c := [3]int{4, 5, 6}
fmt.Println("a == b:", a == b) // true
fmt.Println("a == c:", a == c) // false
}Мы рассмотрели основные операции при работе с массивами, в следующих главах мы рассмотрим устройство массивов более детально.
Leave a Reply