2.6Kпросмотров
33.2%от подписчиков
10 декабря 2025 г.
question📷 ФотоScore: 2.9K
❓ Что выведет программа? И объясни, почему вывод - НЕ тот, который ожидает большинство 🙂 package main import "fmt" func main() { s := []int{1, 2, 3, 4} t := s[:2] // [1 2] u := s[2:] // [3 4] // Изменяем через t t = append(t, 9) // Изменяем через u u[0] = 99 fmt.Println("s:", s) fmt.Println("t:", t) fmt.Println("u:", u)
} 🔥 Разбор t := s[:2] и u := s[2:] смотрят на один и тот же underlying array но append(t, 9) может либо
• дописать в тот же массив, либо
• выделить новый, если capacity закончилась Именно тут начинается путаница: если capacity исходного s >= 5 — append изменит исходный массив, и s, t, u будут видеть изменения друг друга если capacity = 4 — append создаст новый backing array, и t “оторвётся” от s и u То есть вывод зависит от capacity, а её большинство разработчиков не проверяют, но предполагают. ✔️ Добавим интриги — сделай capacity явной 👇
s := make([]int, 4, 4) // capacity = length
copy(s, []int{1,2,3,4}) Теперь: - append(t, 9) создаёт новый массив и t уже не связан с s Вывод будет: s: [1 2 99 4]
t: [1 2 9]
u: [99 4] Но если capacity увеличить: go
s := make([]int, 4, 10) // capacity > length
copy(s, []int{1,2,3,4}) Мы получим: s: [1 2 9 99]
t: [1 2 9]
u: [99 4] Потому что в этот раз append записал в тот же underlying array. В Go поведение slice зависит от capacity --и два, казалось бы, одинаковых куска кода могут работать по-разному без единой строки изменения. 👉 Запустить код