Slice, Go'da dizilerle çalışmanın temel yapısal birimi olan dinamik bir dizidir. Tarihsel olarak, programlama dilleri sabit diziler veya daha ağır yapılar sunmuştur. Go, memory koleksiyonlarını otomatik boyut yönetimi ve uzunluğu değiştirme yeteneği ile işlemek için slices'ı kullanışlı bir araç olarak uygulamıştır.
Sorun bellek yönetimini doğru bir şekilde yapmak, sınır durumlarını (boş, nil, dolu slice'lar) işlemek ve bir slice'ın uzunluğu ile kapasitesi arasındaki farkı anlamaktır.
Çözüm ise yerleşik len(), cap() fonksiyonlarını doğru bir şekilde kullanmak ve Go'nun slice ile ilgili sözleşmelerine uymaktır.
Kod örneği:
var a []int // nil slice, len=0, cap=0 b := make([]int, 0) // boş slice, len=0, cap=0 c := make([]int, 3, 5) // len=3, cap=5 c = append(c, 4, 5, 6) // cap otomatik olarak artırılacak
Anahtar özellikler:
var s []int) hiç bellek tahsis etmez, sadece içsel olarak boş slice'dan (make([]int, 0)) farklıdır.Nil slice'a append yaptığında slice'ın uzunluğu ve kapasitesi ne olur?
Nil slice (var s []int) append(s, 1) sonrasında uzunluğu 1, kapasitesi 1 olan bir slice olur — Go otomatik olarak depolama alanı ayırır.
var s []int s = append(s, 42) // s artık [42], len=1, cap=1
Nil olan bir slice'ın kapasitesine erişilebilir mi?
Evet, nil slice'da len ve cap fonksiyonları her ikisi de 0 döner. Panik olmaz.
var s []int fmt.Println(len(s), cap(s)) // 0 0
Nil olan bir slice'a bellek tahsisi olmadan indeksle bir eleman atamaya çalıştığınızda ne olur?
index out of range hatası alırsınız, çünkü slice'ta hiç eleman yoktur.
var s []int s[0] = 1 // panic: runtime error: index out of range
Ekip, Go sunucusunda her yerde yalnızca var s []T kullanmaya karar verdi ve bunun her zaman make([]T, 0) ile eşdeğer olduğunu beklediler. Sonuç olarak, bazı JSON serileştirmeleri null yerine [] döndürdü.
Artılar:
Eksiler:
make([]T, 0, 100) kullanarak ön tahsis yapıldıktan sonra döngüde sadece append kullanmak. Bu, bellek tahsisini en aza indirir ve genellikle performansta kazanımlar sağlar.
Artılar:
Eksiler: