Слайсы в Go. Советы
Совет №1
Всегда проверяйте слайсы по длине, а не на пустоту. Если слайс не проинициализирован, то он будет nil, а если проинициализировать, то он "как бы содержит уже значения, но в то же время он пустой". Если проверим все три слайса, то len у них будет == 0.
var a []int // nil, len=0
b := []int{} // не nil, len=0
c := make([]int, 0) // не nil, len=0
Как заметили, как у ниловых, так и уже "проинициализированных" слайсов длина равна нулю.
Совет №2
Заранее аллоцируйте память под слайсы. Например, вы пишете функцию, которая принимает слайс и возвращает слайс, внутри вы создадите результирующий слайс, в который положите что-то и вернете: var res []int — такое создание слайса приведет к постоянному его пересозданию в памяти. Вместо этого лучше заранее его аллоцировать и указать cap следующим образом:
func Foo(nums []int) []int {
var res make([]int, 0, cap(nums))
...
}
cap(nums) - указав таким образом вместимость массива, вы уже заложили память под эти элементы.
Совет №3
Если мы хотим изменить переданный в нашу функцию слайс, но не хотим изменять внешний (исходный), то необходимо создать копию исходного и работать уже с его копией:
func foo(list []int) {
newList := make([]int, len(list))
copy(newList, list) // используем copy()
newList = append(newList, 999)
fmt.Println(newList)
}
Здесь копируем данные из list в newList, и в дальнейшем будем оперировать уже новым листом, а исходный list не будет затронут.
Вместо copy можно также использовать:
newList := slices.Clone(list)
А если написать так:
func foo(list []int) {
list[0] = 999
}
то при условии, что объем листа это позволяет, мы изменим нулевое значение у исходного слайса. Для вас это может быть сюрпризом, хоть слайс передан в функцию по значению, а не по ссылке. Почему так происходит, надо узнать что такое слайс под капотом.
Комментарии
0
Ты: ...
Пока нет комментариев. Будь первым.