Я думал, что срезы содержат ссылку на базовый массив. Разве это не так?
Да, это так. Но вы создали массив длиной 3 с этим оператором:
s := []int{1, 2, 3}
Когда вы добавили элемент к ss
, это потребовало выделения нового, более длинного массива. Таким образом, вы потеряли связь между ss
и s
с этим оператором:
ss = append(ss, 4)
Вы можете убедиться в этом, запустив этот пример:
package main
import (
"fmt"
)
func main() {
s := []int{1, 2, 3}
ss := s[1:]
ss[0] += 5
ss = append(ss, 4)
ss[0] += 100
fmt.Println(s)
}
Какой выводится [1 7 3]
.
Если вы измените инициализацию s
, чтобы иметь длину, превышающую три, новое выделение массива не потребуется, и связь между s
и ss
будет сохранена:
package main
import (
"fmt"
)
func main() {
s := make([]int, 3, 4)
s[0], s[1], s[2] = 1, 2, 3
ss := s[1:]
ss[0] += 5
ss = append(ss, 4)
ss[0] += 100
fmt.Println(s)
}
Вывод: [1 107 3]
Ответ, который теоретизирует, что проблема является копией диапазона среза, является неправильным, что можно показать в следующем примере:
package main
import (
"fmt"
)
func main() {
s := make([]int, 3, 4)
s[0], s[1], s[2] = 1, 2, 3
ss := s[1:]
ss = append(ss, 4)
for i := range ss {
ss[i] += 10
}
fmt.Println(s)
}
Выход: [1 12 13]