- Сообщения
- 202
- Реакции
- 0
Как работает append?
Функция
Возможные проблемы:
Как избежать проблем?
Функция
append добавляет элементы в срез и возвращает новый срез. Однако есть нюанс: если емкость исходного среза достаточна, append изменит его. Если нет — создаст новый срез с новым базовым массивом.
Код:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3}
newSlice := append(slice, 4)
slice[0] = 99
fmt.Println(newSlice)
}
Возможные проблемы:
- Если несколько срезов ссылаются на один базовый массив, изменение одного среза может повлиять на другие;
- Если вы сохраняете ссылку на большой массив через под-срез, это может предотвратить сборку мусора для неиспользуемых данных;
- Если вы предполагаете, что append всегда создает новый срез, это может привести к неожиданному поведению.
Как избежать проблем?
- Создавать копии срезов
Если вам нужно изменить срез, не затрагивая исходный, используйте функцию copy или явно создавайте новый срез.
Код:package main import "fmt" func main() { original := []int{1, 2, 3} copied := make([]int, len(original)) copy(copied, original) copied[0] = 99 fmt.Println(original) fmt.Println(copied) } - Используйте полное выражение среза
Если вы создаете под-срез и хотите контролировать его емкость, используйте полное выражение среза (slice[low:high:max]).
Код:package main import "fmt" func main() { original := []int{1, 2, 3, 4, 5} subslice := original[1:4:4] subslice = append(subslice, 6) fmt.Println(original) fmt.Println(subslice) } - Проверяйте емкость перед использованием
append
Если вы хотите быть уверены, что append не изменит исходный срез, проверьте его емкость.
Код:package main import "fmt" func main() { slice := []int{1, 2, 3} if cap(slice) == len(slice) { newSlice := append(slice, 4) fmt.Println(newSlice) } else { newSlice := append(slice, 4) fmt.Println(newSlice) } }