Ответ
Доступ к элементу массива (или среза) по индексу в Go, как для чтения, так и для записи, имеет алгоритмическую сложность O(1) (константное время).
Это возможно потому, что элементы хранятся в непрерывном блоке памяти. Адрес нужного элемента вычисляется мгновенно по формуле:
адрес_элемента = адрес_начала_массива + индекс * размер_одного_элемента
// Массив
arr := [3]int{10, 20, 30}
value := arr[1] // O(1) - прямое вычисление адреса
// Срез (slice)
slice := []int{10, 20, 30}
slice[1] = 25 // O(1) - срез под капотом ссылается на массив
Ключевой момент: время доступа не зависит от количества элементов в массиве или срезе. Доступ к 10-му элементу займет столько же времени, сколько и к 1,000,000-му.
Ответ 18+ 🔞
А, ну ты смотри, какой умный вопрос подъехал! Слушай, а ведь реально, как это работает-то, а? Ну типа, взял ты массив здоровенный, на миллион элементов, и тебе вдруг резко понадобился элемент под индексом 999999. И что, компьютер сейчас начнёт с начала ползти, перебирая все девятьсот девяносто девять тысяч девятьсот девяносто восемь предыдущих? Да хуй там плавал!
Всё гораздо проще, ёпта. Это ж не список какой-нибудь связанный, где от начала до конца скакать надо. Это массив, сука! Он, блядь, как шеренга солдат на плацу — все стоят ровненько, носок к носку, в одном сплошном куске памяти.
И формула там, блядь, проще некуда, в рот меня чих-пых! Компьютер знает, где этот ряд начинается (адрес начала). Знает он и размер одного бойца (размер элемента, int там или string). Ну и индекс ты ему даёшь. И он просто, ёбана-матрешка, делает:
адрес_нужного_чувака = адрес_начала_строя + индекс * размер_одного_чувака
Раз! И всё, приехали. Сложность-то O(1), константная! Не O(n), где от размера зависит, а именно O(1) — один и тот же промежуток времени, хоть для первого элемента, хоть для миллионного. Волшебство, блядь, да и только.
// Вот смотри, объявляем строй
arr := [3]int{10, 20, 30}
value := arr[1] // И сразу, нахуй, прыгаем ко второму. Никакого перебора!
// Со срезом (slice) та же песня. Он ведь под капотом на массив ссылается.
slice := []int{10, 20, 30}
slice[1] = 25 // Оп-па! И запись тоже мгновенная. Прямо по адресу прилетело.
Суть в чём, блядь: время доступа — оно фиксированное. Неважно, десять элементов в массиве или десять миллионов. Доступ к любому по индекру — это как найти дом по точному адресу, а не ходить по всему городу, заглядывая в каждое окно. Вот и вся магия, ёперный театр!