Может кто-нибудь объяснить мне это поведение? - PullRequest
0 голосов
/ 23 октября 2019

Я просто пробовал что-то простое с Голангом и получил такое поведение

Может кто-нибудь объяснить мне, почему? Я чувствую, что неправильно понимаю ...

package main

import (
    "fmt"
)

func main() {
    s := []int{1, 2, 3}
    fmt.Println(s)
    fmt.Println("----")
    a := s[0:2]
    fmt.Println(s)
    fmt.Println(a)
    a = append(a, 5)
    fmt.Println("----")
    fmt.Println(s)
    fmt.Println(a)
    a = append(a, 6)
    fmt.Println("----")
    fmt.Println(s)
    fmt.Println(a)
}

Go Playground

Ответ:

[1 2 3]
----
[1 2 3]
[1 2]
----
[1 2 5]
[1 2 5]
----
[1 2 5]
[1 2 5 6]

Я ожидал:

[1 2 3]
----
[1 2 3]
[1 2]
----
[1 2 3]
[1 2 5]
----
[1 2 3]
[1 2 5 6]

Заранее спасибо, :)

1 Ответ

3 голосов
/ 23 октября 2019

Вы используете ломтик. Срез представляет собой структуру с тремя элементами, один из которых является указателем на массив с данными (второй - емкостью, третий - длиной).

s -> array | 1 | 2 | 3 | 

Далее

a := s[0:2]

Теперь у вас естьдва среза, но оба они указывают на один и тот же массив и срезы совместно используют свои данные.

s -> array | 1 | 2 | 3 | <- a

Далее:

a = append(a, 5)

Здесь вы добавили элемент ко второму срезу, но этосрез разделяет тот же массив с первым срезом, поэтому вы переписали последний последний элемент первого среза (и массива).

s -> array | 1 | 2 | 5 | <- a

Next:

a = append(a, 6)

Здесь вы добавили еще одинодин элемент для второго среза. Но массив, который используется для этого слайса, не может содержать больше элементов, поэтому массив для второго слайса был воссоздан. Go создал новый массив, скопируйте в него все элементы из первого массива и используйте этот новый массив для второго среза. Первый фрагмент все еще использует свой собственный массив.

s -> array | 1 | 2 | 5 | 
a -> array | 1 | 2 | 5 | 6 |
...