Копирование массивов в слайсы в Go - PullRequest
3 голосов
/ 25 февраля 2020

Пожалуйста, вы можете помочь мне понять, как работает генерация среза из массива. Почему ID1 и ID2 не совпадают?

    a := [2]string{"a", "b"}
    b := [2]string{"c", "d"}
    var z [2][2]string
    z[0] = a
    z[1] = b

    fmt.Printf("%s\n", z)
    var id [][]string
    for _, t := range z {
        temp := t[:]
        id = append(id, temp)
    }
    fmt.Printf("\nid1 = %s", id)

    var id2 [][]string
    for _, t := range z {
        temp := t
        id2 = append(id2, temp[:])
    }
    fmt.Printf("\nid2 = %s", id2)

[[ab] [c d]]

id1 = [[c d] [c d]]
id2 = [[ab] [c d]]

Ответы [ 3 ]

5 голосов
/ 25 февраля 2020

Поскольку for range l oop имеет одну переменную итерации, которая повторно используется в каждой итерации. Spe c: Для операторов: Для операторов с предложением for

Переменные, объявленные оператором init, повторно используются в каждой итерации.

Итак, в вашем первом l oop:

for _, t := range z {
    temp := t[:]
    id = append(id, temp)
}

есть один t, и вы нарезаете один и тот же массив t, поэтому каждый добавляемый вами temp срез будет указывать на тот же самый резервный массив, который равен t, и он перезаписывается на каждой итерации, поэтому его значением будет значение последней итерации: [c d].

Во второй секунде l oop:

for _, t := range z {
    temp := t
    id2 = append(id2, temp[:])
}

Также есть одна итерационная переменная t, но вы делаете ее копию: temp := t, и вы разрезаете эту копию, которая отделена от t, и вы добавляете ломтик в качестве резервного массива используется копия, которая не будет перезаписываться на каждой итерации.

4 голосов
/ 25 февраля 2020

Это проблемное задание c. Это не то, что кажется:

temp := t[:]

Здесь t - это массив, а переменная l oop. Это означает, что на каждой итерации содержимое текущего массива копируется в t. На первой итерации t=[]string{"a","b"} создается срез, указывающий на этот массив и назначаемый temp. На второй итерации t перезаписывается и становится []string{"c","d"}. Эта операция также перезаписывает содержимое первого фрагмента. Итак, вы в конечном итоге с {{"c","d"},{"c","d"}}. Важным моментом здесь является то, что содержимое t перезаписывается, а t распределяется между двумя срезами.

2 голосов
/ 26 февраля 2020

В первом l oop вы сохраняете срезы с одинаковым базовым массивом (ie. Переменная l oop t). Во втором l oop вы храните срезы, используя разные резервные массивы, поскольку вы делаете копию t в temp.

...