@Pretendi

Как правильно работать со слайсами?

Я не понимаю как правильно копировать слайсы, так чтобы измения одного не затрагивали другой.
package main

import "fmt"

func Delete(slicePtr *[]int, value int) {
	for i := 0; i < len(*slicePtr); i++ {
		if (*slicePtr)[i] == value {
			if i != 0 {
				*slicePtr = append((*slicePtr)[:i], (*slicePtr)[i+1:len(*slicePtr)]...)
			} else {
				*slicePtr = (*slicePtr)[i+1 : len(*slicePtr)]
				return
			}
		}
	}
}

func main() {
	const Size = 9
	sliceA := make([]int, Size)
	for i := 0; i < Size; i++ {
		sliceA[i] = i + 1
	}
	sliceB := sliceA
	fmt.Println(sliceA, sliceB)
	Delete(&sliceB, 2)
	fmt.Println(sliceA, sliceB)
}

Результат:
go run test.go` | done: 1.550204843s ]
[1 2 3 4 5 6 7 8 9] [1 2 3 4 5 6 7 8 9]
[1 3 4 5 6 7 8 9 9] [1 3 4 5 6 7 8 9]


Содержание sliceA немного удивляет. Документация говорит что изменение слайса затронет слайс с которого он сделан, но не так же! Пример показывает, что содержание поменялось, но не длина.
Более интересен вопрос со структурами, содержащими слайсы. Если я создам копию структуры и начну менять слайс внутри, то это отразится на оригинале. WTF? Получается, нужно писать что-то типа конструктора копирования?
  • Вопрос задан
  • 723 просмотра
Решения вопроса 1
bitver
@bitver
https://github.com/golang/go/wiki/SliceTricks
Там описано всё что нужно)
На счет структур...если нужно иметь возможность deep-copy обьектов, то придется писать что-то вроде конструктора копии (с++), только в Go нет такого, можно написать метод Copy(), который вернёт копию обьекта с новыми указателями, слайсами и новой выделенной под них память. play.golang.org/p/lr9vnTNp-J
UPD: Самому понадобилось, нашёл https://godoc.org/code.google.com/p/rog-go/exp/deepcopy - универсальная реализация копирования.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы