Ответ
Индексирование в Go — это способ доступа к элементам коллекции (массива, среза, строки или карты) по индексу или ключу. Синтаксис — collection[index]
.
1. Индексация массивов и срезов (Arrays/Slices)
Доступ к элементу осуществляется по его целочисленному индексу, нумерация начинается с 0. Выход за пределы среза или массива вызывает панику.
numbers := []int{10, 20, 30}
fmt.Println(numbers[1]) // Выведет: 20
// numbers[3] // вызовет панику: runtime error: index out of range
2. Индексация карт (Maps)
Доступ к значению осуществляется по ключу. Если ключ не найден, возвращается нулевое значение для типа данных значения. Чтобы отличить отсутствующий ключ от ключа с нулевым значением, используется вторая переменная ok
.
ages := map[string]int{"Alice": 25, "Bob": 0}
// Получение значения
fmt.Println(ages["Alice"]) // Выведет: 25
// Проверка наличия ключа
age, ok := ages["Bob"]
fmt.Printf("Bob's age: %d, exists: %tn", age, ok) // Выведет: Bob's age: 0, exists: true
age, ok = ages["Charlie"]
fmt.Printf("Charlie's age: %d, exists: %tn", age, ok) // Выведет: Charlie's age: 0, exists: false
3. Индексация строк (Strings)
Это важный и коварный момент в Go. Строка в Go — это неизменяемая последовательность байт. При индексации строки вы получаете байт по указанному индексу, а не символ (руну).
str := "Привет"
// Неправильный способ доступа к символам в многобайтовой кодировке
fmt.Println(str[0]) // Выведет: 208 (первый байт буквы 'П')
fmt.Println(str[1]) // Выведет: 159 (второй байт буквы 'П')
// Правильный способ — преобразовать строку в срез рун
runes := []rune(str)
fmt.Printf("%cn", runes[0]) // Выведет: П
fmt.Printf("%cn", runes[1]) // Выведет: р
Для безопасной и корректной итерации по символам строки всегда следует использовать цикл for ... range
или предварительное преобразование в []rune
.