«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Почему перетасовка фрагмента влияет на назначенный ему фрагмент в Go?

Почему перетасовка фрагмента влияет на назначенный ему фрагмент в Go?

Опубликовано 11 ноября 2024 г.
Просматривать:941

Why does shuffling a slice affect a slice assigned to it in Go?

Обработка массивов в Go

В Go массивы являются типами значений, и присвоение одного массива другому создает копию всех его элементов. Это справедливо даже при передаче массива в функцию, поскольку она получит копию, а не ссылку на память.

Исходный вопрос

Был поднят запрос относительно следующий код:

package main

import (
    "fmt"
    "rand"
    "time"
)

func shuffle(arr []int) {
    rand.Seed(time.Nanoseconds())
    for i := len(arr) - 1; i > 0; i-- {
        j := rand.Intn(i)
        arr[i], arr[j] = arr[j], arr[i]
    }
}

func main() {
    arr := []int{1, 2, 3, 4, 5}
    arr2 := arr
    shuffle(arr)
    for _, i := range arr2 {
        fmt.Printf("%d ", i)
    }
}

Автор выразил недоумение по поводу того, почему функция перемешивания повлияла на arr2, несмотря на то, что он ожидал, что arr2 и arr будут разными сущностями.

Разъяснение

Проблема возникает из-за неправильного понимания между массивами и срезами.

Массивы и срезы

Массивы представляют собой коллекции значений фиксированной длины, а срезы представляют собой динамические ссылки на базовые массивы. В приведенном примере кода массивы не используются.

Манипулирование срезами

Строка arr := []int{1, 2, 3, 4, 5} создает срез, ссылающийся на анонимный базовый массив. Последующая строка arr2 := arr просто дублирует эту ссылку, в результате чего и arr, и arr2 указывают на один и тот же базовый массив.

Поведение функции

При передаче arr в shuffle, создается копия среза, а не базового массива. Эта копия модифицируется функцией, поэтому arr2 также затрагивается при изменении arr.

Заключение

В Go срезы ведут себя как ссылки на базовые массивы. Присвоение одного фрагмента другому копирует ссылку, а не базовый массив. Эта концепция имеет решающее значение для понимания манипуляций срезами в Go.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3